summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-08 16:11:33 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-08 16:11:33 +0100
commit72e5124b8517662ca2cd25deb5806bc04d20c022 (patch)
tree5950af37125647a6f14369eab667c7d611d1ac69
parenta19c22ebf8775f73b840f52b7e03869166ca0dab (diff)
parenta12f6ba302e54c1570c54aa4c722f2dafbf794af (diff)
Merge remote-tracking branch 'origin/release' into stable
Conflicts: tests/auto/opengl/qgl/tst_qgl.cpp Change-Id: I3c601351c984c1f4b00478d3c47ac9eeb021e892
-rw-r--r--.qmake.conf3
-rw-r--r--mkspecs/features/qt_docs.prf8
-rw-r--r--mkspecs/features/qt_module.prf3
-rw-r--r--qmake/generators/metamakefile.cpp16
-rw-r--r--qmake/generators/metamakefile.h2
-rw-r--r--qmake/main.cpp2
-rw-r--r--src/corelib/tools/qlocale.cpp4
-rw-r--r--src/gui/image/qpixmap_raster.cpp5
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp11
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp26
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h1
-rw-r--r--src/network/kernel/qnetworkproxy.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm33
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm32
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp10
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp38
-rw-r--r--tests/auto/opengl/qgl/tst_qgl.cpp15
-rw-r--r--tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp4
22 files changed, 182 insertions, 53 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 5de255cb69..17dbc553bb 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,2 +1,5 @@
load(qt_build_config)
CONFIG += qt_example_installs
+
+# In qtbase, all modules follow qglobal.h
+MODULE_VERSION = $$QT_VERSION
diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf
index 31f7b65c38..c80efb03e0 100644
--- a/mkspecs/features/qt_docs.prf
+++ b/mkspecs/features/qt_docs.prf
@@ -25,11 +25,13 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR
!build_online_docs: \
QDOC += -installdir $$[QT_INSTALL_DOCS]
qtver.name = QT_VERSION
-qtver.value = $$QT_VERSION
+qtver.value = $$VERSION
+isEmpty(qtver.value): qtver.value = $$MODULE_VERSION
+isEmpty(qtver.value): error("No version for documentation specified.")
qtmver.name = QT_VER
-qtmver.value = $${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}
+qtmver.value = $$replace(qtver.value, ^(\\d+\\.\\d+).*$, \\1)
qtvertag.name = QT_VERSION_TAG
-qtvertag.value = $$replace(QT_VERSION, \.,)
+qtvertag.value = $$replace(qtver.value, \.,)
qtAddToolEnv(QDOC, qtver qtmver qtvertag)
doc_command = $$QDOC $$QMAKE_DOCS
prepare_docs {
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 728d1f5f85..d015b213d7 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -20,7 +20,8 @@
load(qt_build_config) # loads qmodule.pri if hasn't been loaded already
isEmpty(MODULE):MODULE = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0)
-isEmpty(VERSION):VERSION = $$QT_VERSION
+isEmpty(VERSION): VERSION = $$MODULE_VERSION
+isEmpty(VERSION): error("Module does not define version.")
# Compile as shared/DLL or static according to the option given to configure
# unless overridden. Host builds are always static
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index 8c10d7d306..e3fa39c7e4 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -79,7 +79,7 @@ public:
virtual bool init();
virtual int type() const { return BUILDSMETATYPE; }
- virtual bool write(const QString &);
+ virtual bool write();
};
void
@@ -149,7 +149,7 @@ BuildsMetaMakefileGenerator::init()
}
bool
-BuildsMetaMakefileGenerator::write(const QString &oldpwd)
+BuildsMetaMakefileGenerator::write()
{
Build *glue = 0;
if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) {
@@ -181,7 +181,6 @@ BuildsMetaMakefileGenerator::write(const QString &oldpwd)
if(Option::output.fileName().isEmpty() &&
Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE)
Option::output.setFileName(project->first("QMAKE_MAKEFILE").toQString());
- Option::output_dir = oldpwd;
QString build_name = build->name;
if(!build->build.isEmpty()) {
if(!build_name.isEmpty())
@@ -268,7 +267,7 @@ public:
virtual bool init();
virtual int type() const { return SUBDIRSMETATYPE; }
- virtual bool write(const QString &);
+ virtual bool write();
};
bool
@@ -349,7 +348,7 @@ SubdirsMetaMakefileGenerator::init()
} else {
const QString output_name = Option::output.fileName();
Option::output.setFileName(sub->output_file);
- hasError |= !sub->makefile->write(sub->output_dir);
+ hasError |= !sub->makefile->write();
delete sub;
qmakeClearCaches();
sub = 0;
@@ -378,7 +377,7 @@ SubdirsMetaMakefileGenerator::init()
}
bool
-SubdirsMetaMakefileGenerator::write(const QString &oldpwd)
+SubdirsMetaMakefileGenerator::write()
{
bool ret = true;
const QString &pwd = qmake_getpwd();
@@ -397,10 +396,7 @@ SubdirsMetaMakefileGenerator::write(const QString &oldpwd)
printf("Writing %s\n", QDir::cleanPath(Option::output_dir+"/"+
Option::output.fileName()).toLatin1().constData());
}
- QString writepwd = Option::fixPathToLocalOS(qmake_getpwd());
- if(!writepwd.startsWith(Option::fixPathToLocalOS(oldpwd)))
- writepwd = oldpwd;
- if(!(ret = subs.at(i)->makefile->write(writepwd)))
+ if (!(ret = subs.at(i)->makefile->write()))
break;
//restore because I'm paranoid
qmake_setpwd(pwd);
diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h
index 85106a674d..aff2f422a6 100644
--- a/qmake/generators/metamakefile.h
+++ b/qmake/generators/metamakefile.h
@@ -69,7 +69,7 @@ public:
virtual bool init() = 0;
virtual int type() const { return -1; }
- virtual bool write(const QString &oldpwd) = 0;
+ virtual bool write() = 0;
};
QT_END_NAMESPACE
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 5f9fb05449..e339239289 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -187,7 +187,7 @@ int runQMake(int argc, char **argv)
if (!success)
exit_val = 3;
- if(mkfile && !mkfile->write(oldpwd)) {
+ if (mkfile && !mkfile->write()) {
if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
fprintf(stderr, "Unable to generate project file.\n");
else
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 39257158a4..365033d84a 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -736,13 +736,13 @@ QLocale::QLocale(QLocalePrivate &dd)
The separator can be either underscore or a minus sign.
If the string violates the locale format, or language is not
- a valid ISO 369 code, the "C" locale is used instead. If country
+ a valid ISO 639 code, the "C" locale is used instead. If country
is not present, or is not a valid ISO 3166 code, the most
appropriate country is chosen for the specified language.
The language, script and country codes are converted to their respective
\c Language, \c Script and \c Country enums. After this conversion is
- performed the constructor behaves exactly like QLocale(Country, Script,
+ performed, the constructor behaves exactly like QLocale(Country, Script,
Language).
This constructor is much slower than QLocale(Country, Script, Language).
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index f0cb69f3ec..f8fef9cada 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -239,8 +239,9 @@ QImage QRasterPlatformPixmap::toImage(const QRect &rect) const
return image;
QRect clipped = rect.intersected(QRect(0, 0, w, h));
- if (d % 8 == 0)
- return QImage(image.scanLine(clipped.y()) + clipped.x() * (d / 8),
+ const uint du = uint(d);
+ if ((du % 8 == 0) && (((uint(clipped.x()) * du)) % 32 == 0))
+ return QImage(image.scanLine(clipped.y()) + clipped.x() * (du / 8),
clipped.width(), clipped.height(),
image.bytesPerLine(), image.format());
else
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 1ba55aa7f1..1de955bc13 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -290,11 +290,14 @@ void QCosmeticStroker::setup()
ppl = buffer->bytesPerLine()>>2;
}
+ // dashes are sensitive to clips, so we need to clip consistently when painting to the same device
+ QRect clipRect = strokeSelection & Dashed ? deviceRect : clip;
+
// setup FP clip bounds
- xmin = clip.left() - 1;
- xmax = clip.right() + 2;
- ymin = clip.top() - 1;
- ymax = clip.bottom() + 2;
+ xmin = clipRect.left() - 1;
+ xmax = clipRect.right() + 2;
+ ymin = clipRect.top() - 1;
+ ymax = clipRect.bottom() + 2;
lastPixel.x = -1;
}
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
index 136b014424..f4fb5fab30 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -85,8 +85,9 @@ public:
HorizontalMask = 0xc
};
- QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr)
+ QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr, const QRect &dr_unclipped)
: state(s),
+ deviceRect(dr_unclipped),
clip(dr),
pattern(0),
reversePattern(0),
@@ -110,6 +111,7 @@ public:
QRasterPaintEngineState *state;
+ QRect deviceRect;
QRect clip;
// clip bounds in real
qreal xmin, xmax;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index aaa0a4b87e..941e3ea71a 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1054,20 +1054,20 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
void QRasterPaintEnginePrivate::systemStateChanged()
{
- QRect clipRect(0, 0,
+ deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
if (!systemClip.isEmpty()) {
- QRegion clippedDeviceRgn = systemClip & clipRect;
+ QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
} else {
- deviceRect = clipRect;
+ deviceRect = deviceRectUnclipped;
baseClip->setClipRect(deviceRect);
}
#ifdef QT_DEBUG_DRAW
- qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << clipRect << systemClip;
+ qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << deviceRectUnclipped << systemClip;
#endif
exDeviceRect = deviceRect;
@@ -1529,7 +1529,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@@ -1576,7 +1576,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@@ -1610,7 +1610,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
@@ -1953,7 +1953,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
if (s->penData.blend) {
QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@@ -2018,7 +2018,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@@ -3112,7 +3112,7 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@@ -3132,7 +3132,7 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
return;
}
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@@ -3153,7 +3153,7 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
const QLine &l = lines[i];
@@ -3225,7 +3225,7 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (!s->penData.blend)
return;
if (s->flags.fast_pen) {
- QCosmeticStroker stroker(s, d->deviceRect);
+ QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
QLineF line = lines[i];
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index e90cad6d8a..d9e4a4b505 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -323,6 +323,7 @@ public:
#endif
QRect deviceRect;
+ QRect deviceRectUnclipped;
QStroker basicStroker;
QScopedPointer<QDashStroker> dashStroker;
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 242855eaba..54229295bb 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -706,7 +706,7 @@ quint16 QNetworkProxy::port() const
If a QAbstractSocket or QTcpSocket has the
QNetworkProxy::DefaultProxy type, then the QNetworkProxy set with
this function is used. If you want more flexibility in determining
- which the proxy, use the QNetworkProxyFactory class.
+ which proxy is used, use the QNetworkProxyFactory class.
Setting a default proxy value with this function will override the
application proxy factory set with
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 55f94df45a..e756c375f3 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -202,6 +202,14 @@ static void cleanupCocoaApplicationDelegate()
if ([self canQuit]) {
if (!startedQuit) {
startedQuit = true;
+ // Close open windows. This is done in order to deliver de-expose
+ // events while the event loop is still running.
+ const QWindowList topLevels = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < topLevels.size(); ++i) {
+ QWindow *window = topLevels.at(i);
+ topLevels.at(i)->close();
+ }
+
QGuiApplication::exit(0);
startedQuit = false;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 2422788f7a..08c516b4f4 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -108,6 +108,7 @@ public:
void setWindowIcon(const QIcon &icon);
void raise();
void lower();
+ bool isExposed() const;
void propagateSizeHints();
void setOpacity(qreal level);
void setMask(const QRegion &region);
@@ -144,6 +145,8 @@ public:
QCocoaMenuBar *menubar() const;
qreal devicePixelRatio() const;
+ void exposeWindow();
+ void obscureWindow();
protected:
// NSWindow handling. The QCocoaWindow/QNSView can either be displayed
// in an existing NSWindow or in one created by Qt.
@@ -178,6 +181,7 @@ public: // for QNSView
bool m_hasModalSession;
bool m_frameStrutEventsEnabled;
+ bool m_isExposed;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 0091028896..30b6d6d84a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -200,6 +200,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_menubar(0)
, m_hasModalSession(false)
, m_frameStrutEventsEnabled(false)
+ , m_isExposed(false)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -284,9 +285,12 @@ void QCocoaWindow::setVisible(bool visible)
}
- // Make sure the QWindow has a frame ready before we show the NSWindow.
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- QWindowSystemInterface::flushWindowSystemEvents();
+ // This call is here to handle initial window show correctly:
+ // - top-level windows need to have backing store content ready when the
+ // window is shown, sendin the expose event here makes that more likely.
+ // - QNSViews for child windows are initialy not hidden and won't get the
+ // viewDidUnhide message.
+ exposeWindow();
if (m_nsWindow) {
// setWindowState might have been called while the window was hidden and
@@ -338,8 +342,6 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
- if (!QCoreApplication::closingDown())
- QWindowSystemInterface::handleExposeEvent(window(), QRegion());
}
}
@@ -489,6 +491,11 @@ void QCocoaWindow::lower()
[m_nsWindow orderBack: m_nsWindow];
}
+bool QCocoaWindow::isExposed() const
+{
+ return m_isExposed;
+}
+
void QCocoaWindow::propagateSizeHints()
{
QCocoaAutoReleasePool pool;
@@ -873,6 +880,22 @@ qreal QCocoaWindow::devicePixelRatio() const
}
}
+void QCocoaWindow::exposeWindow()
+{
+ if (!m_isExposed) {
+ m_isExposed = true;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ }
+}
+
+void QCocoaWindow::obscureWindow()
+{
+ if (m_isExposed) {
+ m_isExposed = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+ }
+}
+
QMargins QCocoaWindow::frameMargins() const
{
NSRect frameW = [m_nsWindow frame];
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index b4b3379a82..853b4b99e1 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -59,6 +59,7 @@ QT_END_NAMESPACE
QPoint m_backingStoreOffset;
CGImageRef m_maskImage;
uchar *m_maskData;
+ bool m_shouldInvalidateWindowShadow;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
@@ -76,9 +77,12 @@ QT_END_NAMESPACE
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
- (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset;
- (void)setMaskRegion:(const QRegion *)region;
+- (void)invalidateWindowShadowIfNeeded;
- (void)drawRect:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)windowNotification : (NSNotification *) windowNotification;
+- (void)viewDidHide;
+- (void)viewDidUnhide;
- (BOOL)isFlipped;
- (BOOL)acceptsFirstResponder;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 02635ea4ec..0c122eaf2d 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -80,6 +80,7 @@ static QTouchDevice *touchDevice = 0;
m_backingStore = 0;
m_maskImage = 0;
m_maskData = 0;
+ m_shouldInvalidateWindowShadow = false;
m_window = 0;
m_buttons = Qt::NoButton;
m_sendKeyEvent = false;
@@ -266,10 +267,10 @@ static QTouchDevice *touchDevice = 0;
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowMinimized);
} else if (notificationName == NSWindowDidDeminiaturizeNotification) {
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState);
- // Qt expects an expose event after restore/deminiaturize. This also needs
- // to be a non-synchronous event to make sure it gets processed after
- // the state change event sent above.
- QWindowSystemInterface::handleExposeEvent(m_window, QRegion(m_window->geometry()));
+ } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
+ m_platformWindow->obscureWindow();
+ } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
+ m_platformWindow->exposeWindow();
} else {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -285,6 +286,16 @@ static QTouchDevice *touchDevice = 0;
}
}
+- (void)viewDidHide
+{
+ m_platformWindow->obscureWindow();
+}
+
+- (void)viewDidUnhide
+{
+ m_platformWindow->exposeWindow();
+}
+
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
@@ -295,13 +306,14 @@ static QTouchDevice *touchDevice = 0;
- (void) setMaskRegion:(const QRegion *)region
{
+ m_shouldInvalidateWindowShadow = true;
if (m_maskImage)
CGImageRelease(m_maskImage);
if (region->isEmpty()) {
m_maskImage = 0;
}
- const QRect &rect = qt_mac_toQRect([self frame]);
+ const QRect &rect = region->boundingRect();
QImage maskImage(rect.size(), QImage::Format_RGB888);
maskImage.fill(Qt::white);
QPainter p(&maskImage);
@@ -314,6 +326,14 @@ static QTouchDevice *touchDevice = 0;
m_maskImage = qt_mac_toCGImage(maskImage, true, &m_maskData);
}
+- (void)invalidateWindowShadowIfNeeded
+{
+ if (m_shouldInvalidateWindowShadow && m_platformWindow->m_nsWindow) {
+ [m_platformWindow->m_nsWindow invalidateShadow];
+ m_shouldInvalidateWindowShadow = false;
+ }
+}
+
- (void) drawRect:(NSRect)dirtyRect
{
if (!m_backingStore)
@@ -368,6 +388,8 @@ static QTouchDevice *touchDevice = 0;
CGContextRestoreGState(cgContext);
CGImageRelease(cleanImg);
CGImageRelease(subMask);
+
+ [self invalidateWindowShadowIfNeeded];
}
- (BOOL) isFlipped
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index f5298a1690..61f53a5073 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -167,6 +167,8 @@ private slots:
void scaled_QTBUG19157();
void detachOnLoad_QTBUG29639();
+
+ void copyOnNonAlignedBoundary();
};
static bool lenientCompare(const QPixmap &actual, const QPixmap &expected)
@@ -1503,5 +1505,13 @@ void tst_QPixmap::detachOnLoad_QTBUG29639()
QVERIFY(a.toImage() != b.toImage());
}
+void tst_QPixmap::copyOnNonAlignedBoundary()
+{
+ QImage img(8, 2, QImage::Format_RGB16);
+
+ QPixmap pm1 = QPixmap::fromImage(img, Qt::NoFormatConversion);
+ QPixmap pm2 = pm1.copy(QRect(5, 0, 3, 2)); // When copying second line: 2 bytes too many are read which might cause an access violation.
+}
+
QTEST_MAIN(tst_QPixmap)
#include "tst_qpixmap.moc"
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index cf520c06a9..774ade5fb0 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -280,6 +280,7 @@ private slots:
void drawTextWithComplexBrush();
void QTBUG26013_squareCapStroke();
void QTBUG25153_drawLine();
+ void dashing_systemClip();
private:
void fillData();
@@ -4461,6 +4462,43 @@ void tst_QPainter::QTBUG25153_drawLine()
}
}
+static void dashing_systemClip_paint(QPainter *p)
+{
+ p->setPen(QPen(Qt::black, 1, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin));
+ p->drawLine(8, 8, 42, 8);
+ p->drawLine(42, 8, 42, 42);
+ p->drawLine(42, 42, 8, 42);
+ p->drawLine(8, 42, 8, 8);
+}
+
+void tst_QPainter::dashing_systemClip()
+{
+ QImage image(50, 50, QImage::Format_RGB32);
+ image.fill(Qt::white);
+
+ QPainter p(&image);
+ dashing_systemClip_paint(&p);
+ p.end();
+
+ QImage old = image.copy();
+
+ image.paintEngine()->setSystemClip(QRect(10, 0, image.width() - 10, image.height()));
+
+ p.begin(&image);
+ dashing_systemClip_paint(&p);
+
+ // doing same paint operation again with different system clip should not change the image
+ QCOMPARE(old, image);
+
+ old = image;
+
+ p.setClipRect(QRect(20, 20, 30, 30));
+ dashing_systemClip_paint(&p);
+
+ // ditto for regular clips
+ QCOMPARE(old, image);
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"
diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp
index 3bae5d5103..00973cf533 100644
--- a/tests/auto/opengl/qgl/tst_qgl.cpp
+++ b/tests/auto/opengl/qgl/tst_qgl.cpp
@@ -832,10 +832,19 @@ static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceI
class UnclippedWidget : public QWidget
{
public:
+ bool painted;
+
+ UnclippedWidget()
+ : painted(false)
+ {
+ }
+
void paintEvent(QPaintEvent *)
{
QPainter p(this);
p.fillRect(rect().adjusted(-1000, -1000, 1000, 1000), Qt::black);
+
+ painted = true;
}
};
@@ -866,10 +875,8 @@ void tst_QGL::graphicsViewClipping()
scene.setSceneRect(view.viewport()->rect());
QVERIFY(QTest::qWaitForWindowExposed(&view));
- #ifdef Q_OS_MAC
- // The black rectangle jumps from the center to the upper left for some reason.
- QTest::qWait(100);
- #endif
+
+ QTRY_VERIFY(widget->painted);
QImage image = viewport->grabFrameBuffer();
QImage expected = image;
diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp
index f16fe49712..2d3e3c1702 100644
--- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp
+++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp
@@ -103,6 +103,10 @@ void tst_QToolTip::task183679()
QFETCH(Qt::Key, key);
QFETCH(bool, visible);
+#ifdef Q_OS_MAC
+ QSKIP("This test fails in the CI system, QTBUG-30040");
+#endif
+
Widget_task183679 widget;
widget.show();
QApplication::setActiveWindow(&widget);