Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: Icc9b061c56e969756f0351c936cdeb8063c86079
This commit is contained in:
commit
043f99954f
@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib
|
|||||||
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
|
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
|
||||||
QMAKE_LIBDIR =
|
QMAKE_LIBDIR =
|
||||||
|
|
||||||
# sdk.prf will prefix the proper SDK sysroot
|
# qtConfLibrary_openglMakeSpec will prefix the proper SDK sysroot
|
||||||
QMAKE_INCDIR_OPENGL = \
|
QMAKE_INCDIR_OPENGL = \
|
||||||
/System/Library/Frameworks/OpenGL.framework/Headers \
|
/System/Library/Frameworks/OpenGL.framework/Headers \
|
||||||
/System/Library/Frameworks/AGL.framework/Headers/
|
/System/Library/Frameworks/AGL.framework/Headers/
|
||||||
|
@ -33,10 +33,6 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path)
|
|||||||
QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath)
|
QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath)
|
||||||
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
|
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
|
||||||
|
|
||||||
sysrootified =
|
|
||||||
for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val
|
|
||||||
QMAKE_INCDIR_OPENGL = $$sysrootified
|
|
||||||
|
|
||||||
QMAKESPEC_NAME = $$basename(QMAKESPEC)
|
QMAKESPEC_NAME = $$basename(QMAKESPEC)
|
||||||
|
|
||||||
# Resolve SDK version of various tools
|
# Resolve SDK version of various tools
|
||||||
|
@ -1454,6 +1454,7 @@ void VcprojGenerator::initTranslationFiles()
|
|||||||
vcProject.TranslationFiles.Guid = _GUIDTranslationFiles;
|
vcProject.TranslationFiles.Guid = _GUIDTranslationFiles;
|
||||||
|
|
||||||
vcProject.TranslationFiles.addFiles(project->values("TRANSLATIONS"));
|
vcProject.TranslationFiles.addFiles(project->values("TRANSLATIONS"));
|
||||||
|
vcProject.TranslationFiles.addFiles(project->values("EXTRA_TRANSLATIONS"));
|
||||||
|
|
||||||
vcProject.TranslationFiles.Project = this;
|
vcProject.TranslationFiles.Project = this;
|
||||||
vcProject.TranslationFiles.Config = &(vcProject.Configuration);
|
vcProject.TranslationFiles.Config = &(vcProject.Configuration);
|
||||||
@ -1576,7 +1577,7 @@ void VcprojGenerator::initExtraCompilerOutputs()
|
|||||||
const ProStringList &tmp_in = project->values(project->first(ProKey(*it + ".input")).toKey());
|
const ProStringList &tmp_in = project->values(project->first(ProKey(*it + ".input")).toKey());
|
||||||
for (int i = 0; i < tmp_in.count(); ++i) {
|
for (int i = 0; i < tmp_in.count(); ++i) {
|
||||||
const QString &filename = tmp_in.at(i).toQString();
|
const QString &filename = tmp_in.at(i).toQString();
|
||||||
if (extraCompilerSources.contains(filename))
|
if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename))
|
||||||
extraCompile.addFile(Option::fixPathToTargetOS(
|
extraCompile.addFile(Option::fixPathToTargetOS(
|
||||||
replaceExtraCompilerVariables(filename, tmp_out, QString(), NoShell), false));
|
replaceExtraCompilerVariables(filename, tmp_out, QString(), NoShell), false));
|
||||||
}
|
}
|
||||||
@ -1592,7 +1593,7 @@ void VcprojGenerator::initExtraCompilerOutputs()
|
|||||||
const ProStringList &tmp_in = project->values(inputVar.toKey());
|
const ProStringList &tmp_in = project->values(inputVar.toKey());
|
||||||
for (int i = 0; i < tmp_in.count(); ++i) {
|
for (int i = 0; i < tmp_in.count(); ++i) {
|
||||||
const QString &filename = tmp_in.at(i).toQString();
|
const QString &filename = tmp_in.at(i).toQString();
|
||||||
if (extraCompilerSources.contains(filename))
|
if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename))
|
||||||
extraCompile.addFile(Option::fixPathToTargetOS(
|
extraCompile.addFile(Option::fixPathToTargetOS(
|
||||||
replaceExtraCompilerVariables(filename, QString(), QString(), NoShell), false));
|
replaceExtraCompilerVariables(filename, QString(), QString(), NoShell), false));
|
||||||
}
|
}
|
||||||
@ -1606,6 +1607,28 @@ void VcprojGenerator::initExtraCompilerOutputs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VcprojGenerator::otherFiltersContain(const QString &fileName) const
|
||||||
|
{
|
||||||
|
auto filterFileMatches = [&fileName] (const VCFilterFile &ff)
|
||||||
|
{
|
||||||
|
return ff.file == fileName;
|
||||||
|
};
|
||||||
|
for (const VCFilter *filter : { &vcProject.RootFiles,
|
||||||
|
&vcProject.SourceFiles,
|
||||||
|
&vcProject.HeaderFiles,
|
||||||
|
&vcProject.GeneratedFiles,
|
||||||
|
&vcProject.LexYaccFiles,
|
||||||
|
&vcProject.TranslationFiles,
|
||||||
|
&vcProject.FormFiles,
|
||||||
|
&vcProject.ResourceFiles,
|
||||||
|
&vcProject.DeploymentFiles,
|
||||||
|
&vcProject.DistributionFiles}) {
|
||||||
|
if (std::any_of(filter->Files.cbegin(), filter->Files.cend(), filterFileMatches))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -132,6 +132,7 @@ private:
|
|||||||
ProString firstInputFileName(const ProString &extraCompilerName) const;
|
ProString firstInputFileName(const ProString &extraCompilerName) const;
|
||||||
QString firstExpandedOutputFileName(const ProString &extraCompilerName);
|
QString firstExpandedOutputFileName(const ProString &extraCompilerName);
|
||||||
void createCustomBuildToolFakeFile(const QString &cbtFilePath, const QString &realOutFilePath);
|
void createCustomBuildToolFakeFile(const QString &cbtFilePath, const QString &realOutFilePath);
|
||||||
|
bool otherFiltersContain(const QString &fileName) const;
|
||||||
friend class VCFilter;
|
friend class VCFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2676,9 +2676,9 @@ QStringList QCoreApplication::libraryPaths()
|
|||||||
QStringList *app_libpaths = new QStringList;
|
QStringList *app_libpaths = new QStringList;
|
||||||
coreappdata()->app_libpaths.reset(app_libpaths);
|
coreappdata()->app_libpaths.reset(app_libpaths);
|
||||||
|
|
||||||
const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
|
QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH");
|
||||||
if (!libPathEnv.isEmpty()) {
|
if (!libPathEnv.isEmpty()) {
|
||||||
QStringList paths = QFile::decodeName(libPathEnv).split(QDir::listSeparator(), QString::SkipEmptyParts);
|
QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
|
||||||
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
|
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
|
||||||
QString canonicalPath = QDir(*it).canonicalPath();
|
QString canonicalPath = QDir(*it).canonicalPath();
|
||||||
if (!canonicalPath.isEmpty()
|
if (!canonicalPath.isEmpty()
|
||||||
|
@ -95,7 +95,7 @@ class QEventDispatcherWin32Private;
|
|||||||
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
||||||
|
|
||||||
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
|
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
|
||||||
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
|
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0),
|
||||||
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
|
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
|
||||||
wakeUps(0), activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL)
|
wakeUps(0), activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL)
|
||||||
{
|
{
|
||||||
@ -552,7 +552,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
wakeUp(); // trigger a call to sendPostedEvents()
|
wakeUp(); // trigger a call to sendPostedEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
d->interrupt = false;
|
d->interrupt.store(false);
|
||||||
emit awake();
|
emit awake();
|
||||||
|
|
||||||
bool canWait;
|
bool canWait;
|
||||||
@ -568,7 +568,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
pHandles = &d->winEventNotifierActivatedEvent;
|
pHandles = &d->winEventNotifierActivatedEvent;
|
||||||
}
|
}
|
||||||
QVarLengthArray<MSG> processedTimers;
|
QVarLengthArray<MSG> processedTimers;
|
||||||
while (!d->interrupt) {
|
while (!d->interrupt.load()) {
|
||||||
MSG msg;
|
MSG msg;
|
||||||
bool haveMessage;
|
bool haveMessage;
|
||||||
|
|
||||||
@ -649,7 +649,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
|
|
||||||
// still nothing - wait for message or signalled objects
|
// still nothing - wait for message or signalled objects
|
||||||
canWait = (!retVal
|
canWait = (!retVal
|
||||||
&& !d->interrupt
|
&& !d->interrupt.load()
|
||||||
&& (flags & QEventLoop::WaitForMoreEvents));
|
&& (flags & QEventLoop::WaitForMoreEvents));
|
||||||
if (canWait) {
|
if (canWait) {
|
||||||
emit aboutToBlock();
|
emit aboutToBlock();
|
||||||
@ -1022,7 +1022,7 @@ void QEventDispatcherWin32::wakeUp()
|
|||||||
void QEventDispatcherWin32::interrupt()
|
void QEventDispatcherWin32::interrupt()
|
||||||
{
|
{
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(QEventDispatcherWin32);
|
||||||
d->interrupt = true;
|
d->interrupt.store(true);
|
||||||
wakeUp();
|
wakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,8 +165,7 @@ public:
|
|||||||
|
|
||||||
DWORD threadId;
|
DWORD threadId;
|
||||||
|
|
||||||
bool interrupt;
|
QAtomicInt interrupt;
|
||||||
bool closingDown;
|
|
||||||
|
|
||||||
// internal window handle used for socketnotifiers/timers/etc
|
// internal window handle used for socketnotifiers/timers/etc
|
||||||
HWND internalHwnd;
|
HWND internalHwnd;
|
||||||
@ -193,9 +192,11 @@ public:
|
|||||||
void postActivateSocketNotifiers();
|
void postActivateSocketNotifiers();
|
||||||
void doWsaAsyncSelect(int socket, long event);
|
void doWsaAsyncSelect(int socket, long event);
|
||||||
|
|
||||||
|
bool closingDown = false;
|
||||||
|
|
||||||
|
bool winEventNotifierListModified = false;
|
||||||
HANDLE winEventNotifierActivatedEvent;
|
HANDLE winEventNotifierActivatedEvent;
|
||||||
QList<QWinEventNotifier *> winEventNotifierList;
|
QList<QWinEventNotifier *> winEventNotifierList;
|
||||||
bool winEventNotifierListModified = false;
|
|
||||||
void activateEventNotifier(QWinEventNotifier * wen);
|
void activateEventNotifier(QWinEventNotifier * wen);
|
||||||
|
|
||||||
QList<MSG> queuedUserInputEvents;
|
QList<MSG> queuedUserInputEvents;
|
||||||
|
@ -2175,8 +2175,10 @@ void QObject::removeEventFilter(QObject *obj)
|
|||||||
|
|
||||||
Note that entering and leaving a new event loop (e.g., by opening a modal
|
Note that entering and leaving a new event loop (e.g., by opening a modal
|
||||||
dialog) will \e not perform the deferred deletion; for the object to be
|
dialog) will \e not perform the deferred deletion; for the object to be
|
||||||
deleted, the control must return to the event loop from which
|
deleted, the control must return to the event loop from which deleteLater()
|
||||||
deleteLater() was called.
|
was called. This does not apply to objects deleted while a previous, nested
|
||||||
|
event loop was still running: the Qt event loop will delete those objects
|
||||||
|
as soon as the new nested event loop starts.
|
||||||
|
|
||||||
\b{Note:} It is safe to call this function more than once; when the
|
\b{Note:} It is safe to call this function more than once; when the
|
||||||
first deferred deletion event is delivered, any pending events for the
|
first deferred deletion event is delivered, any pending events for the
|
||||||
|
@ -448,7 +448,7 @@
|
|||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
{ "type": "pkgConfig", "args": "gl", "condition": "!config.darwin" },
|
{ "type": "pkgConfig", "args": "gl", "condition": "!config.darwin" },
|
||||||
{ "type": "makeSpec", "spec": "OPENGL" }
|
{ "type": "openglMakeSpec" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"opengl_es2": {
|
"opengl_es2": {
|
||||||
|
@ -15,6 +15,17 @@ defineTest(qtConfLibrary_freetype) {
|
|||||||
return(true)
|
return(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineTest(qtConfLibrary_openglMakeSpec) {
|
||||||
|
darwin:sdk {
|
||||||
|
sysrootified =
|
||||||
|
for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val
|
||||||
|
QMAKE_INCDIR_OPENGL = $$sysrootified
|
||||||
|
}
|
||||||
|
$${1}.spec = OPENGL
|
||||||
|
!qtConfLibrary_makeSpec($$1, $$2): return(false)
|
||||||
|
return(true)
|
||||||
|
}
|
||||||
|
|
||||||
# Check for Direct X shader compiler 'fxc'.
|
# Check for Direct X shader compiler 'fxc'.
|
||||||
# Up to Direct X SDK June 2010 and for MinGW, this is pointed to by the
|
# Up to Direct X SDK June 2010 and for MinGW, this is pointed to by the
|
||||||
# DXSDK_DIR variable. Starting with Windows Kit 8, it is included in
|
# DXSDK_DIR variable. Starting with Windows Kit 8, it is included in
|
||||||
|
@ -695,13 +695,29 @@ QList<QTouchEvent::TouchPoint>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (states == Qt::TouchPointReleased) {
|
if (states == Qt::TouchPointReleased) {
|
||||||
g_nextPointId = 1;
|
// All points on deviceId have been released.
|
||||||
g_pointIdMap->clear();
|
// Remove all points associated with that device from g_pointIdMap.
|
||||||
|
// (On other devices, some touchpoints might still be pressed.
|
||||||
|
// But this function is only called with points from one device at a time.)
|
||||||
|
for (auto it = g_pointIdMap->begin(); it != g_pointIdMap->end();) {
|
||||||
|
if (it.key() >> 32 == quint64(deviceId))
|
||||||
|
it = g_pointIdMap->erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
if (g_pointIdMap->isEmpty())
|
||||||
|
g_nextPointId = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return touchPoints;
|
return touchPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWindowSystemInterfacePrivate::clearPointIdMap()
|
||||||
|
{
|
||||||
|
g_pointIdMap->clear();
|
||||||
|
g_nextPointId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QWindowSystemInterface::TouchPoint>
|
QList<QWindowSystemInterface::TouchPoint>
|
||||||
QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
|
||||||
const QWindow *window)
|
const QWindow *window)
|
||||||
|
@ -537,6 +537,7 @@ public:
|
|||||||
static QList<QWindowSystemInterface::TouchPoint>
|
static QList<QWindowSystemInterface::TouchPoint>
|
||||||
toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
|
toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
|
||||||
const QWindow *window);
|
const QWindow *window);
|
||||||
|
static void clearPointIdMap();
|
||||||
|
|
||||||
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
|
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
|
||||||
static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
|
static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
|
||||||
|
@ -297,7 +297,7 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
|
|||||||
QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent)
|
QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent)
|
||||||
: QObject(*new QSyntaxHighlighterPrivate, parent)
|
: QObject(*new QSyntaxHighlighterPrivate, parent)
|
||||||
{
|
{
|
||||||
if (parent->inherits("QTextEdit")) {
|
if (parent && parent->inherits("QTextEdit")) {
|
||||||
QTextDocument *doc = parent->property("document").value<QTextDocument *>();
|
QTextDocument *doc = parent->property("document").value<QTextDocument *>();
|
||||||
if (doc)
|
if (doc)
|
||||||
setDocument(doc);
|
setDocument(doc);
|
||||||
|
@ -62,9 +62,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
|
|||||||
QEglFSScreen::~QEglFSScreen()
|
QEglFSScreen::~QEglFSScreen()
|
||||||
{
|
{
|
||||||
delete m_cursor;
|
delete m_cursor;
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
QOpenGLCompositor::destroy();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect QEglFSScreen::geometry() const
|
QRect QEglFSScreen::geometry() const
|
||||||
|
@ -62,6 +62,7 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
|
|||||||
: QPlatformWindow(w),
|
: QPlatformWindow(w),
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
m_backingStore(0),
|
m_backingStore(0),
|
||||||
|
m_rasterCompositingContext(0),
|
||||||
#endif
|
#endif
|
||||||
m_raster(false),
|
m_raster(false),
|
||||||
m_winId(0),
|
m_winId(0),
|
||||||
@ -144,18 +145,18 @@ void QEglFSWindow::create()
|
|||||||
|
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
if (isRaster()) {
|
if (isRaster()) {
|
||||||
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
|
m_rasterCompositingContext = new QOpenGLContext;
|
||||||
context->setShareContext(qt_gl_global_share_context());
|
m_rasterCompositingContext->setShareContext(qt_gl_global_share_context());
|
||||||
context->setFormat(m_format);
|
m_rasterCompositingContext->setFormat(m_format);
|
||||||
context->setScreen(window()->screen());
|
m_rasterCompositingContext->setScreen(window()->screen());
|
||||||
if (Q_UNLIKELY(!context->create()))
|
if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
|
||||||
qFatal("EGLFS: Failed to create compositing context");
|
qFatal("EGLFS: Failed to create compositing context");
|
||||||
compositor->setTarget(context, window(), screen->rawGeometry());
|
compositor->setTarget(m_rasterCompositingContext, window(), screen->rawGeometry());
|
||||||
compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"));
|
compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"));
|
||||||
// If there is a "root" window into which raster and QOpenGLWidget content is
|
// If there is a "root" window into which raster and QOpenGLWidget content is
|
||||||
// composited, all other contexts must share with its context.
|
// composited, all other contexts must share with its context.
|
||||||
if (!qt_gl_global_share_context()) {
|
if (!qt_gl_global_share_context()) {
|
||||||
qt_gl_set_global_share_context(context);
|
qt_gl_set_global_share_context(m_rasterCompositingContext);
|
||||||
// What we set up here is in effect equivalent to the application setting
|
// What we set up here is in effect equivalent to the application setting
|
||||||
// AA_ShareOpenGLContexts. Set the attribute to be fully consistent.
|
// AA_ShareOpenGLContexts. Set the attribute to be fully consistent.
|
||||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||||
@ -166,6 +167,10 @@ void QEglFSWindow::create()
|
|||||||
|
|
||||||
void QEglFSWindow::destroy()
|
void QEglFSWindow::destroy()
|
||||||
{
|
{
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
QOpenGLCompositor::instance()->removeWindow(this);
|
||||||
|
#endif
|
||||||
|
|
||||||
QEglFSScreen *screen = this->screen();
|
QEglFSScreen *screen = this->screen();
|
||||||
if (m_flags.testFlag(HasNativeWindow)) {
|
if (m_flags.testFlag(HasNativeWindow)) {
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
@ -177,12 +182,14 @@ void QEglFSWindow::destroy()
|
|||||||
screen->setPrimarySurface(EGL_NO_SURFACE);
|
screen->setPrimarySurface(EGL_NO_SURFACE);
|
||||||
|
|
||||||
invalidateSurface();
|
invalidateSurface();
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
QOpenGLCompositor::destroy();
|
||||||
|
delete m_rasterCompositingContext;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_flags = 0;
|
m_flags = 0;
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
QOpenGLCompositor::instance()->removeWindow(this);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEglFSWindow::invalidateSurface()
|
void QEglFSWindow::invalidateSurface()
|
||||||
|
@ -116,6 +116,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
QOpenGLCompositorBackingStore *m_backingStore;
|
QOpenGLCompositorBackingStore *m_backingStore;
|
||||||
|
QOpenGLContext *m_rasterCompositingContext;
|
||||||
#endif
|
#endif
|
||||||
bool m_raster;
|
bool m_raster;
|
||||||
WId m_winId;
|
WId m_winId;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
TARGET = qhaiku
|
TARGET = qhaiku
|
||||||
|
|
||||||
QT += core-private gui-private eventdistpatcher_support-private
|
QT += core-private gui-private eventdispatcher_support-private
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
@ -1099,6 +1099,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
|||||||
return false;
|
return false;
|
||||||
case QtWindows::ClipboardEvent:
|
case QtWindows::ClipboardEvent:
|
||||||
return false;
|
return false;
|
||||||
|
case QtWindows::CursorEvent: // Sent to windows that do not have capture (see QTBUG-58590).
|
||||||
|
if (QWindowsCursor::hasOverrideCursor()) {
|
||||||
|
QWindowsCursor::enforceOverrideCursor();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case QtWindows::UnknownEvent:
|
case QtWindows::UnknownEvent:
|
||||||
return false;
|
return false;
|
||||||
case QtWindows::AccessibleObjectFromWindowRequest:
|
case QtWindows::AccessibleObjectFromWindowRequest:
|
||||||
|
@ -1912,7 +1912,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
bool click = (index == d->pressedIndex && index.isValid());
|
bool click = (index == d->pressedIndex && index.isValid());
|
||||||
bool selectedClicked = click && (event->button() == Qt::LeftButton) && d->pressedAlreadySelected;
|
bool selectedClicked = click && (event->button() == Qt::LeftButton) && d->pressedAlreadySelected;
|
||||||
EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
|
EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
|
||||||
bool edited = edit(index, trigger, event);
|
const bool edited = click ? edit(index, trigger, event) : false;
|
||||||
|
|
||||||
d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
|
d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
|
||||||
|
|
||||||
|
@ -1315,8 +1315,8 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
|
|||||||
if (tl.isValid() && br.isValid()
|
if (tl.isValid() && br.isValid()
|
||||||
&& d->isIndexEnabled(tl)
|
&& d->isIndexEnabled(tl)
|
||||||
&& d->isIndexEnabled(br)) {
|
&& d->isIndexEnabled(br)) {
|
||||||
QRect first = rectForIndex(tl);
|
QRect first = d->cellRectForIndex(tl);
|
||||||
QRect last = rectForIndex(br);
|
QRect last = d->cellRectForIndex(br);
|
||||||
QRect middle;
|
QRect middle;
|
||||||
if (d->flow == LeftToRight) {
|
if (d->flow == LeftToRight) {
|
||||||
QRect &top = first;
|
QRect &top = first;
|
||||||
|
@ -333,14 +333,31 @@ public:
|
|||||||
inline QModelIndex listViewItemToIndex(const QListViewItem &item) const
|
inline QModelIndex listViewItemToIndex(const QListViewItem &item) const
|
||||||
{ return model->index(commonListView->itemIndex(item), column, root); }
|
{ return model->index(commonListView->itemIndex(item), column, root); }
|
||||||
|
|
||||||
|
inline bool hasRectForIndex(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return isIndexValid(index) && index.parent() == root && index.column() == column && !isHidden(index.row());
|
||||||
|
}
|
||||||
|
|
||||||
QRect rectForIndex(const QModelIndex &index) const
|
QRect rectForIndex(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!isIndexValid(index) || index.parent() != root || index.column() != column || isHidden(index.row()))
|
if (!hasRectForIndex(index))
|
||||||
return QRect();
|
return QRect();
|
||||||
executePostedLayout();
|
executePostedLayout();
|
||||||
return viewItemRect(indexToListViewItem(index));
|
return viewItemRect(indexToListViewItem(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect cellRectForIndex(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (!hasRectForIndex(index))
|
||||||
|
return QRect();
|
||||||
|
executePostedLayout();
|
||||||
|
auto oldItemAlignment = itemAlignment;
|
||||||
|
itemAlignment = Qt::Alignment();
|
||||||
|
const QRect rect = rectForIndex(index);
|
||||||
|
itemAlignment = oldItemAlignment;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
void viewUpdateGeometries() { q_func()->updateGeometries(); }
|
void viewUpdateGeometries() { q_func()->updateGeometries(); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,6 +204,7 @@ private slots:
|
|||||||
void basicRawEventTranslationOfIds();
|
void basicRawEventTranslationOfIds();
|
||||||
void multiPointRawEventTranslationOnTouchScreen();
|
void multiPointRawEventTranslationOnTouchScreen();
|
||||||
void multiPointRawEventTranslationOnTouchPad();
|
void multiPointRawEventTranslationOnTouchPad();
|
||||||
|
void touchOnMultipleTouchscreens();
|
||||||
void deleteInEventHandler();
|
void deleteInEventHandler();
|
||||||
void deleteInRawEventTranslation();
|
void deleteInRawEventTranslation();
|
||||||
void crashInQGraphicsSceneAfterNotHandlingTouchBegin();
|
void crashInQGraphicsSceneAfterNotHandlingTouchBegin();
|
||||||
@ -213,11 +214,13 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QTouchDevice *touchScreenDevice;
|
QTouchDevice *touchScreenDevice;
|
||||||
|
QTouchDevice *secondaryTouchScreenDevice;
|
||||||
QTouchDevice *touchPadDevice;
|
QTouchDevice *touchPadDevice;
|
||||||
};
|
};
|
||||||
|
|
||||||
tst_QTouchEvent::tst_QTouchEvent()
|
tst_QTouchEvent::tst_QTouchEvent()
|
||||||
: touchScreenDevice(QTest::createTouchDevice())
|
: touchScreenDevice(QTest::createTouchDevice())
|
||||||
|
, secondaryTouchScreenDevice(QTest::createTouchDevice())
|
||||||
, touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad))
|
, touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -225,6 +228,7 @@ tst_QTouchEvent::tst_QTouchEvent()
|
|||||||
void tst_QTouchEvent::cleanup()
|
void tst_QTouchEvent::cleanup()
|
||||||
{
|
{
|
||||||
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
|
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
|
||||||
|
QWindowSystemInterfacePrivate::clearPointIdMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QTouchEvent::qPointerUniqueId()
|
void tst_QTouchEvent::qPointerUniqueId()
|
||||||
@ -951,6 +955,157 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTouchEvent::touchOnMultipleTouchscreens()
|
||||||
|
{
|
||||||
|
tst_QTouchEventWidget touchWidget;
|
||||||
|
touchWidget.setWindowTitle(QTest::currentTestFunction());
|
||||||
|
touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
|
touchWidget.setGeometry(100, 100, 400, 300);
|
||||||
|
touchWidget.show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&touchWidget));
|
||||||
|
QWindow *window = touchWidget.windowHandle();
|
||||||
|
|
||||||
|
QPointF pos = touchWidget.rect().center();
|
||||||
|
QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint());
|
||||||
|
QPointF delta(10, 10);
|
||||||
|
QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget);
|
||||||
|
|
||||||
|
QVector<QTouchEvent::TouchPoint> rawTouchPoints(3);
|
||||||
|
rawTouchPoints[0].setId(0);
|
||||||
|
rawTouchPoints[1].setId(10);
|
||||||
|
rawTouchPoints[2].setId(11);
|
||||||
|
|
||||||
|
// this should be translated to a TouchBegin
|
||||||
|
rawTouchPoints[0].setState(Qt::TouchPointPressed);
|
||||||
|
rawTouchPoints[0].setScreenPos(screenPos);
|
||||||
|
rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
|
||||||
|
rawTouchPoints[0].setRawScreenPositions({{12, 34}, {56, 78}});
|
||||||
|
ulong timestamp = 1234;
|
||||||
|
QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(touchWidget.seenTouchBegin);
|
||||||
|
QVERIFY(!touchWidget.seenTouchUpdate);
|
||||||
|
QVERIFY(!touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
|
||||||
|
QCOMPARE(touchWidget.timestamp, timestamp);
|
||||||
|
QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
|
||||||
|
const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
|
||||||
|
const int secTouchPointId = (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2;
|
||||||
|
QCOMPARE(touchBeginPoint.id(), touchPointId);
|
||||||
|
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[0].state());
|
||||||
|
QCOMPARE(touchBeginPoint.pos(), pos);
|
||||||
|
|
||||||
|
// press a point on secondaryTouchScreenDevice
|
||||||
|
touchWidget.seenTouchBegin = false;
|
||||||
|
rawTouchPoints[1].setState(Qt::TouchPointPressed);
|
||||||
|
rawTouchPoints[1].setScreenPos(screenPos);
|
||||||
|
rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
|
||||||
|
rawTouchPoints[1].setRawScreenPositions({{90, 100}, {110, 120}});
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(!touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
|
||||||
|
QCOMPARE(touchWidget.timestamp, timestamp);
|
||||||
|
touchBeginPoint = touchWidget.touchBeginPoints[0];
|
||||||
|
QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2);
|
||||||
|
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[1].state());
|
||||||
|
QCOMPARE(touchBeginPoint.pos(), pos);
|
||||||
|
|
||||||
|
// press another point on secondaryTouchScreenDevice
|
||||||
|
touchWidget.seenTouchBegin = false;
|
||||||
|
rawTouchPoints[2].setState(Qt::TouchPointPressed);
|
||||||
|
rawTouchPoints[2].setScreenPos(screenPos);
|
||||||
|
rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry));
|
||||||
|
rawTouchPoints[2].setRawScreenPositions({{130, 140}, {150, 160}});
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(!touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
|
||||||
|
QCOMPARE(touchWidget.timestamp, timestamp);
|
||||||
|
touchBeginPoint = touchWidget.touchBeginPoints[0];
|
||||||
|
QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 3);
|
||||||
|
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[2].state());
|
||||||
|
QCOMPARE(touchBeginPoint.pos(), pos);
|
||||||
|
|
||||||
|
// moving the first point should translate to TouchUpdate
|
||||||
|
rawTouchPoints[0].setState(Qt::TouchPointMoved);
|
||||||
|
rawTouchPoints[0].setScreenPos(screenPos + delta);
|
||||||
|
rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(touchWidget.seenTouchBegin);
|
||||||
|
QVERIFY(touchWidget.seenTouchUpdate);
|
||||||
|
QVERIFY(!touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
|
||||||
|
QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
|
||||||
|
QCOMPARE(touchUpdatePoint.id(), touchPointId);
|
||||||
|
QCOMPARE(touchUpdatePoint.state(), rawTouchPoints[0].state());
|
||||||
|
QCOMPARE(touchUpdatePoint.pos(), pos + delta);
|
||||||
|
|
||||||
|
// releasing the first point translates to TouchEnd
|
||||||
|
rawTouchPoints[0].setState(Qt::TouchPointReleased);
|
||||||
|
rawTouchPoints[0].setScreenPos(screenPos + delta + delta);
|
||||||
|
rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(touchWidget.seenTouchBegin);
|
||||||
|
QVERIFY(touchWidget.seenTouchUpdate);
|
||||||
|
QVERIFY(touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchEndPoints.count(), 1);
|
||||||
|
QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
|
||||||
|
QCOMPARE(touchEndPoint.id(), touchPointId);
|
||||||
|
QCOMPARE(touchEndPoint.state(), rawTouchPoints[0].state());
|
||||||
|
QCOMPARE(touchEndPoint.pos(), pos + delta + delta);
|
||||||
|
|
||||||
|
// Widgets don't normally handle this case: if a TouchEnd was seen before, then
|
||||||
|
// WA_WState_AcceptedTouchBeginEvent will be false, and
|
||||||
|
// QApplicationPrivate::translateRawTouchEvent will ignore touch events that aren't TouchBegin.
|
||||||
|
// So we have to set it true. It _did_ in fact accept the touch begin from the secondary device,
|
||||||
|
// but it also got a TouchEnd from the primary device in the meantime.
|
||||||
|
touchWidget.setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, true);
|
||||||
|
|
||||||
|
// Releasing one point on the secondary touchscreen does not yet generate TouchEnd.
|
||||||
|
touchWidget.seenTouchEnd = false;
|
||||||
|
touchWidget.touchEndPoints.clear();
|
||||||
|
rawTouchPoints[1].setState(Qt::TouchPointReleased);
|
||||||
|
rawTouchPoints[2].setState(Qt::TouchPointStationary);
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1] << rawTouchPoints[2], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(touchWidget.seenTouchBegin);
|
||||||
|
QVERIFY(touchWidget.seenTouchUpdate);
|
||||||
|
QVERIFY(!touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
|
||||||
|
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), secTouchPointId);
|
||||||
|
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), secTouchPointId + 1);
|
||||||
|
|
||||||
|
// releasing the last point on the secondary touchscreen translates to TouchEnd
|
||||||
|
touchWidget.seenTouchEnd = false;
|
||||||
|
rawTouchPoints[2].setState(Qt::TouchPointReleased);
|
||||||
|
nativeTouchPoints =
|
||||||
|
QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window);
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QVERIFY(touchWidget.seenTouchBegin);
|
||||||
|
QVERIFY(touchWidget.seenTouchUpdate);
|
||||||
|
QVERIFY(touchWidget.seenTouchEnd);
|
||||||
|
QCOMPARE(touchWidget.touchEndPoints.count(), 1);
|
||||||
|
touchEndPoint = touchWidget.touchEndPoints.first();
|
||||||
|
QCOMPARE(touchEndPoint.id(), secTouchPointId + 1);
|
||||||
|
QCOMPARE(touchEndPoint.state(), rawTouchPoints[2].state());
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
|
void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
|
||||||
{
|
{
|
||||||
tst_QTouchEventWidget touchWidget;
|
tst_QTouchEventWidget touchWidget;
|
||||||
|
@ -121,6 +121,7 @@ private slots:
|
|||||||
void task254449_draggingItemToNegativeCoordinates();
|
void task254449_draggingItemToNegativeCoordinates();
|
||||||
void keyboardSearch();
|
void keyboardSearch();
|
||||||
void shiftSelectionWithNonUniformItemSizes();
|
void shiftSelectionWithNonUniformItemSizes();
|
||||||
|
void shiftSelectionWithItemAlignment();
|
||||||
void clickOnViewportClearsSelection();
|
void clickOnViewportClearsSelection();
|
||||||
void task262152_setModelColumnNavigate();
|
void task262152_setModelColumnNavigate();
|
||||||
void taskQTBUG_2233_scrollHiddenItems_data();
|
void taskQTBUG_2233_scrollHiddenItems_data();
|
||||||
@ -1802,6 +1803,51 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QListView::shiftSelectionWithItemAlignment()
|
||||||
|
{
|
||||||
|
QStringList items;
|
||||||
|
for (int c = 0; c < 2; c++) {
|
||||||
|
for (int i = 10; i > 0; i--)
|
||||||
|
items << QString(i, QLatin1Char('*'));
|
||||||
|
|
||||||
|
for (int i = 1; i < 11; i++)
|
||||||
|
items << QString(i, QLatin1Char('*'));
|
||||||
|
}
|
||||||
|
|
||||||
|
QListView view;
|
||||||
|
view.setFlow(QListView::TopToBottom);
|
||||||
|
view.setWrapping(true);
|
||||||
|
view.setItemAlignment(Qt::AlignLeft);
|
||||||
|
view.setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
|
QStringListModel model(items);
|
||||||
|
view.setModel(&model);
|
||||||
|
|
||||||
|
QFont font = view.font();
|
||||||
|
font.setPixelSize(10);
|
||||||
|
view.setFont(font);
|
||||||
|
view.resize(300, view.sizeHintForRow(0) * items.size() / 2 + view.horizontalScrollBar()->height());
|
||||||
|
|
||||||
|
view.show();
|
||||||
|
QApplication::setActiveWindow(&view);
|
||||||
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
||||||
|
QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
|
||||||
|
|
||||||
|
QModelIndex index1 = view.model()->index(items.size() / 4, 0);
|
||||||
|
QPoint p = view.visualRect(index1).center();
|
||||||
|
QVERIFY(view.viewport()->rect().contains(p));
|
||||||
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p);
|
||||||
|
QCOMPARE(view.currentIndex(), index1);
|
||||||
|
QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
|
||||||
|
|
||||||
|
QModelIndex index2 = view.model()->index(items.size() / 4 * 3, 0);
|
||||||
|
p = view.visualRect(index2).center();
|
||||||
|
QVERIFY(view.viewport()->rect().contains(p));
|
||||||
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p);
|
||||||
|
QCOMPARE(view.currentIndex(), index2);
|
||||||
|
QCOMPARE(view.selectionModel()->selectedIndexes().size(), index2.row() - index1.row() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QListView::clickOnViewportClearsSelection()
|
void tst_QListView::clickOnViewportClearsSelection()
|
||||||
{
|
{
|
||||||
QStringList items;
|
QStringList items;
|
||||||
|
@ -200,6 +200,7 @@ private slots:
|
|||||||
void taskQTBUG_45697_crash();
|
void taskQTBUG_45697_crash();
|
||||||
void taskQTBUG_7232_AllowUserToControlSingleStep();
|
void taskQTBUG_7232_AllowUserToControlSingleStep();
|
||||||
void taskQTBUG_8376();
|
void taskQTBUG_8376();
|
||||||
|
void taskQTBUG_61476();
|
||||||
void testInitialFocus();
|
void testInitialFocus();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4806,5 +4807,58 @@ void tst_QTreeView::taskQTBUG_8376()
|
|||||||
QCOMPARE(rowHeightLvl1Visible, rowHeightLvl1Visible2);
|
QCOMPARE(rowHeightLvl1Visible, rowHeightLvl1Visible2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTreeView::taskQTBUG_61476()
|
||||||
|
{
|
||||||
|
// This checks that if a user clicks on an item to collapse it that it
|
||||||
|
// does not edit (in this case change the check state) the item that is
|
||||||
|
// now over the mouse just because it got a release event
|
||||||
|
QTreeView tv;
|
||||||
|
QStandardItemModel model;
|
||||||
|
QStandardItem *lastTopLevel = nullptr;
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
QStandardItem *item = new QStandardItem(QLatin1String("Row Item"));
|
||||||
|
item->setCheckable(true);
|
||||||
|
item->setCheckState(Qt::Checked);
|
||||||
|
model.appendRow(item);
|
||||||
|
lastTopLevel = item;
|
||||||
|
for (int j = 0; j < 2; ++j) {
|
||||||
|
QStandardItem *childItem = new QStandardItem(QLatin1String("Child row Item"));
|
||||||
|
childItem->setCheckable(true);
|
||||||
|
childItem->setCheckState(Qt::Checked);
|
||||||
|
item->appendRow(childItem);
|
||||||
|
QStandardItem *grandChild = new QStandardItem(QLatin1String("Grand child row Item"));
|
||||||
|
grandChild->setCheckable(true);
|
||||||
|
grandChild->setCheckState(Qt::Checked);
|
||||||
|
childItem->appendRow(grandChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tv.setModel(&model);
|
||||||
|
tv.expandAll();
|
||||||
|
// We need it to be this size so that the effect of the collapsing will
|
||||||
|
// cause the parent item to move to be under the cursor
|
||||||
|
tv.resize(200, 200);
|
||||||
|
tv.show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowActive(&tv));
|
||||||
|
tv.verticalScrollBar()->setValue(tv.verticalScrollBar()->maximum());
|
||||||
|
|
||||||
|
// We want to press specifically right around where a checkbox for the
|
||||||
|
// parent item could be when collapsing
|
||||||
|
QTreeViewPrivate *priv = static_cast<QTreeViewPrivate*>(qt_widget_private(&tv));
|
||||||
|
const QModelIndex mi = lastTopLevel->child(0)->index();
|
||||||
|
const QRect rect = priv->itemDecorationRect(mi);
|
||||||
|
const QPoint pos = rect.center();
|
||||||
|
|
||||||
|
QTest::mousePress(tv.viewport(), Qt::LeftButton, 0, pos);
|
||||||
|
if (tv.style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, &tv) ==
|
||||||
|
QEvent::MouseButtonPress)
|
||||||
|
QTRY_VERIFY(!tv.isExpanded(mi));
|
||||||
|
|
||||||
|
QTest::mouseRelease(tv.viewport(), Qt::LeftButton, 0, pos);
|
||||||
|
QTRY_VERIFY(!tv.isExpanded(mi));
|
||||||
|
QCOMPARE(lastTopLevel->checkState(), Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QTreeView)
|
QTEST_MAIN(tst_QTreeView)
|
||||||
#include "tst_qtreeview.moc"
|
#include "tst_qtreeview.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user