Merge remote-tracking branch 'origin/5.11.1' into 5.11
Change-Id: I9a4571ccf826a86e055dfbba23b5e5cbd8ea55e8
This commit is contained in:
commit
8eabb44f8a
144
dist/changes-5.11.1
vendored
Normal file
144
dist/changes-5.11.1
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
Qt 5.11.1 is a bug-fix release. It maintains both forward and backward
|
||||
compatibility (source and binary) with Qt 5.11.0.
|
||||
|
||||
For more details, refer to the online documentation included in this
|
||||
distribution. The documentation is also available online:
|
||||
|
||||
http://doc.qt.io/qt-5/index.html
|
||||
|
||||
The Qt version 5.11 series is binary compatible with the 5.10.x series.
|
||||
Applications compiled for 5.10 will continue to run with 5.11.
|
||||
|
||||
Some of the changes listed in this file include issue tracking numbers
|
||||
corresponding to tasks in the Qt Bug Tracker:
|
||||
|
||||
https://bugreports.qt.io/
|
||||
|
||||
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||
information about a particular change.
|
||||
|
||||
****************************************************************************
|
||||
* Important Behavior Changes *
|
||||
****************************************************************************
|
||||
|
||||
- [QTBUG-68619] In Qt 5.11.0, support for selecting a platform plugin
|
||||
based on the XDG_SESSION_TYPE environment variable was added. On
|
||||
gnome-shell, however, bugs—in both Qt and gnome-shell—made many
|
||||
widget applications almost unusable. So until those bugs are fixed
|
||||
XDG_SESSION_TYPE=wayland is now ignored on gnome-shell.
|
||||
|
||||
****************************************************************************
|
||||
* Library *
|
||||
****************************************************************************
|
||||
|
||||
QtCore
|
||||
------
|
||||
|
||||
- Item Models:
|
||||
* [QTBUG-18001] Fixed a bug that made selecting or deselecting a column if
|
||||
some flags are applied to certain items.
|
||||
* [QTBUG-44962][QTBUG-67948][QTBUG-68427] Fixed issues with the replacing
|
||||
of the source model in QSortFilterProxyModel that could lead to empty
|
||||
views or failed assertions.
|
||||
|
||||
- QJsonDocument
|
||||
* [QTBUG-61969] Fixed a number of bugs in the parsing of binary data
|
||||
(QJson::fromRawData) that could lead to crashes or out-of-bounds access.
|
||||
|
||||
- QLocale:
|
||||
* On Unix, when using LANGUAGE would lose information about script or
|
||||
country, without changing language, use the locale implied by LC_ALL,
|
||||
LC_MESSAGES or LANG.
|
||||
|
||||
- QPointF/QRectF:
|
||||
* [QTBUG-60359][QTBUG-62161] Fixed an issue that led to inconsistent
|
||||
comparison results for the different edges of a rectangle.
|
||||
|
||||
- QProcess:
|
||||
* [QTBUG-68472] On Unix, the QProcess SIGCHLD handler now restores errno
|
||||
on exit.
|
||||
* [QTBUG-67744] QProcess now properly reports an error state if it failed
|
||||
to create the communication pipes.
|
||||
|
||||
- QSharedPointer:
|
||||
* [QTBUG-68300] Fixed a problem that made create() on a type with const
|
||||
qualification fail to compile.
|
||||
|
||||
QtNetwork
|
||||
---------
|
||||
|
||||
- QNetworkCookieJar:
|
||||
* [QTBUG-52040] Cookies will no longer be rejected when the domain
|
||||
matches a TLD. However (to avoid problems with TLDs), such cookies are
|
||||
only accepted, or sent, when the host name matches exactly.
|
||||
|
||||
QtWidgets
|
||||
---------
|
||||
|
||||
- [QTBUG-48325] Sending a key press event with sendEvent() now sends a
|
||||
ShortCutOverride event first to the widget to trigger any shortcuts set
|
||||
first.
|
||||
- [QTBUG-67533] QOpenGLWidget/QQuickWidget is now respecting AlwaysStackOnTop.
|
||||
- [QTBUG-60404] Fixed crash in QMacPanGestureRecognizer.
|
||||
- [QTBUG-67836] Fixed input method commits that end with newline.
|
||||
- [QTBUG-33855] Fixed issue with fonts in QHeaderViews
|
||||
- [QTBUG-56457] Fixed margin issue related to sections in QHeaderView.
|
||||
|
||||
****************************************************************************
|
||||
* Platform-specific Changes *
|
||||
****************************************************************************
|
||||
|
||||
Android
|
||||
-------
|
||||
|
||||
- [QTBUG-68344] QTemporaryFile does not try to use O_TMPFILE any more,
|
||||
to work around outdated sandbox restrictions of linkat(). This also fixes
|
||||
use of QSettings and QFile::copy().
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
- [QTBUG-68586] Fixed a bug that caused QFileSystemWatcher to print a warning
|
||||
if the file being watched did not exist. The class is documented to return
|
||||
the list of files that it could not watch.
|
||||
|
||||
macOS
|
||||
-----
|
||||
|
||||
- [QTBUG-60676] Fixed a bug in using QFileSystemWatcher to watch different
|
||||
file paths that shared a common prefix.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
- [QTBUG-68514] Reverted a change that caused static binaries compiled
|
||||
with Visual Studio 2015 to crash on start-up. Note that this does not
|
||||
apply to Visual Studio 2017 static binaries, even though the crash stack
|
||||
traces are very similar: with 2017, the problem is compiler regression
|
||||
and requires updating to version 15.8 for the fix.
|
||||
|
||||
****************************************************************************
|
||||
* Tools *
|
||||
****************************************************************************
|
||||
|
||||
configure & build system
|
||||
------------------------
|
||||
|
||||
- [QTBUG-68478] Fixed parallel build of examples in some modules.
|
||||
|
||||
qmake
|
||||
-----
|
||||
|
||||
- [QTBUG-37417][CMake] Fixed missing include paths in private modules.
|
||||
- [QTBUG-47325] Fixed crash when $QMAKEFEATURES contains empty paths
|
||||
(e.g., due to a trailing colon).
|
||||
- [QTBUG-52474][Xcode] Fixed sources being excluded from Time Machine
|
||||
backups.
|
||||
- [QTBUG-66462][Darwin] Fixed overriding QMAKE_TARGET_BUNDLE_PREFIX in
|
||||
project files.
|
||||
- [QTBUG-68705][Xcode] Fixed build directory location of app bundles.
|
||||
- [Xcode] Fixed compatibility with Xcode 10 by opting out from the new
|
||||
build system.
|
||||
- [Darwin] Fixed .prl file lookup for suffixed frameworks.
|
||||
- Fixed look-up of relative files from extra compilers' .depend_command
|
||||
in shadow builds.
|
@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
|
@ -1613,7 +1613,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
// The configuration build dir however is not treated as excluded,
|
||||
// so we can safely point it to the root output dir.
|
||||
t << "\t\t\t\t" << writeSettings("CONFIGURATION_BUILD_DIR",
|
||||
Option::output_dir + Option::dir_sep + "$(CONFIGURATION)") << ";\n";
|
||||
Option::output_dir + Option::dir_sep + "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)") << ";\n";
|
||||
|
||||
if (!project->isEmpty("DESTDIR")) {
|
||||
ProString dir = project->first("DESTDIR");
|
||||
|
@ -294,3 +294,54 @@ function(QT5_ADD_RESOURCES outfiles )
|
||||
endfunction()
|
||||
|
||||
set(_Qt5_COMPONENT_PATH "${CMAKE_CURRENT_LIST_DIR}/..")
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.9)
|
||||
macro(qt5_use_modules _target _link_type)
|
||||
if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.11)
|
||||
if(CMAKE_WARN_DEPRECATED)
|
||||
set(messageType WARNING)
|
||||
endif()
|
||||
if(CMAKE_ERROR_DEPRECATED)
|
||||
set(messageType FATAL_ERROR)
|
||||
endif()
|
||||
if(messageType)
|
||||
message(${messageType} "The qt5_use_modules macro is obsolete. Use target_link_libraries with IMPORTED targets instead.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT TARGET ${_target})
|
||||
message(FATAL_ERROR "The first argument to qt5_use_modules must be an existing target.")
|
||||
endif()
|
||||
if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE" )
|
||||
set(_qt5_modules ${ARGN})
|
||||
set(_qt5_link_type ${_link_type})
|
||||
else()
|
||||
set(_qt5_modules ${_link_type} ${ARGN})
|
||||
endif()
|
||||
|
||||
if ("${_qt5_modules}" STREQUAL "")
|
||||
message(FATAL_ERROR "qt5_use_modules requires at least one Qt module to use.")
|
||||
endif()
|
||||
|
||||
foreach(_module ${_qt5_modules})
|
||||
if (NOT Qt5${_module}_FOUND)
|
||||
find_package(Qt5${_module} PATHS "${_Qt5_COMPONENT_PATH}" NO_DEFAULT_PATH)
|
||||
if (NOT Qt5${_module}_FOUND)
|
||||
message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${_target} ${_qt5_link_type} ${Qt5${_module}_LIBRARIES})
|
||||
set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${Qt5${_module}_INCLUDE_DIRS})
|
||||
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${Qt5${_module}_COMPILE_DEFINITIONS})
|
||||
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
|
||||
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
|
||||
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE
|
||||
AND (CMAKE_VERSION VERSION_LESS 2.8.12
|
||||
AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
||||
OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)))
|
||||
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
endif()
|
||||
|
@ -216,18 +216,6 @@
|
||||
# // Numerical checks are preferred to named checks, but to be safe
|
||||
# // we define the missing version names in case Qt uses them.
|
||||
#
|
||||
# if !defined(__MAC_10_7)
|
||||
# define __MAC_10_7 1070
|
||||
# endif
|
||||
# if !defined(__MAC_10_8)
|
||||
# define __MAC_10_8 1080
|
||||
# endif
|
||||
# if !defined(__MAC_10_9)
|
||||
# define __MAC_10_9 1090
|
||||
# endif
|
||||
# if !defined(__MAC_10_10)
|
||||
# define __MAC_10_10 101000
|
||||
# endif
|
||||
# if !defined(__MAC_10_11)
|
||||
# define __MAC_10_11 101100
|
||||
# endif
|
||||
@ -237,17 +225,8 @@
|
||||
# if !defined(__MAC_10_13)
|
||||
# define __MAC_10_13 101300
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_7)
|
||||
# define MAC_OS_X_VERSION_10_7 1070
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_8)
|
||||
# define MAC_OS_X_VERSION_10_8 1080
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_9)
|
||||
# define MAC_OS_X_VERSION_10_9 1090
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_10)
|
||||
# define MAC_OS_X_VERSION_10_10 101000
|
||||
# if !defined(__MAC_10_14)
|
||||
# define __MAC_10_14 101400
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_11)
|
||||
# define MAC_OS_X_VERSION_10_11 101100
|
||||
@ -258,55 +237,10 @@
|
||||
# if !defined(MAC_OS_X_VERSION_10_13)
|
||||
# define MAC_OS_X_VERSION_10_13 101300
|
||||
# endif
|
||||
# if !defined(MAC_OS_X_VERSION_10_14)
|
||||
# define MAC_OS_X_VERSION_10_14 101400
|
||||
# endif
|
||||
#
|
||||
# if !defined(__IPHONE_4_3)
|
||||
# define __IPHONE_4_3 40300
|
||||
# endif
|
||||
# if !defined(__IPHONE_5_0)
|
||||
# define __IPHONE_5_0 50000
|
||||
# endif
|
||||
# if !defined(__IPHONE_5_1)
|
||||
# define __IPHONE_5_1 50100
|
||||
# endif
|
||||
# if !defined(__IPHONE_6_0)
|
||||
# define __IPHONE_6_0 60000
|
||||
# endif
|
||||
# if !defined(__IPHONE_6_1)
|
||||
# define __IPHONE_6_1 60100
|
||||
# endif
|
||||
# if !defined(__IPHONE_7_0)
|
||||
# define __IPHONE_7_0 70000
|
||||
# endif
|
||||
# if !defined(__IPHONE_7_1)
|
||||
# define __IPHONE_7_1 70100
|
||||
# endif
|
||||
# if !defined(__IPHONE_8_0)
|
||||
# define __IPHONE_8_0 80000
|
||||
# endif
|
||||
# if !defined(__IPHONE_8_1)
|
||||
# define __IPHONE_8_1 80100
|
||||
# endif
|
||||
# if !defined(__IPHONE_8_2)
|
||||
# define __IPHONE_8_2 80200
|
||||
# endif
|
||||
# if !defined(__IPHONE_8_3)
|
||||
# define __IPHONE_8_3 80300
|
||||
# endif
|
||||
# if !defined(__IPHONE_8_4)
|
||||
# define __IPHONE_8_4 80400
|
||||
# endif
|
||||
# if !defined(__IPHONE_9_0)
|
||||
# define __IPHONE_9_0 90000
|
||||
# endif
|
||||
# if !defined(__IPHONE_9_1)
|
||||
# define __IPHONE_9_1 90100
|
||||
# endif
|
||||
# if !defined(__IPHONE_9_2)
|
||||
# define __IPHONE_9_2 90200
|
||||
# endif
|
||||
# if !defined(__IPHONE_9_3)
|
||||
# define __IPHONE_9_3 90300
|
||||
# endif
|
||||
# if !defined(__IPHONE_10_0)
|
||||
# define __IPHONE_10_0 100000
|
||||
# endif
|
||||
@ -322,6 +256,9 @@
|
||||
# if !defined(__IPHONE_11_0)
|
||||
# define __IPHONE_11_0 110000
|
||||
# endif
|
||||
# if !defined(__IPHONE_12_0)
|
||||
# define __IPHONE_12_0 120000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __LSB_VERSION__
|
||||
|
@ -120,7 +120,7 @@ mac {
|
||||
|
||||
LIBS_PRIVATE += -framework Foundation
|
||||
|
||||
osx: LIBS_PRIVATE += -framework CoreServices -framework AppKit
|
||||
osx: LIBS_PRIVATE += -framework CoreServices -framework AppKit -framework Security
|
||||
|
||||
ios|tvos {
|
||||
# We need UIKit for UIApplication in qeventdispatcher_cf.mm
|
||||
|
@ -44,6 +44,10 @@
|
||||
#include <AppKit/NSText.h>
|
||||
#endif
|
||||
|
||||
#if defined(QT_PLATFORM_UIKIT)
|
||||
#include <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -189,6 +193,43 @@ AppleApplication *qt_apple_sharedApplication()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED)
|
||||
bool qt_apple_isSandboxed()
|
||||
{
|
||||
static bool isSandboxed = []() {
|
||||
QCFType<SecStaticCodeRef> staticCode = nullptr;
|
||||
NSURL *bundleUrl = [[NSBundle mainBundle] bundleURL];
|
||||
if (SecStaticCodeCreateWithPath((__bridge CFURLRef)bundleUrl,
|
||||
kSecCSDefaultFlags, &staticCode) != errSecSuccess)
|
||||
return false;
|
||||
|
||||
QCFType<SecRequirementRef> sandboxRequirement;
|
||||
if (SecRequirementCreateWithString(CFSTR("entitlement[\"com.apple.security.app-sandbox\"] exists"),
|
||||
kSecCSDefaultFlags, &sandboxRequirement) != errSecSuccess)
|
||||
return false;
|
||||
|
||||
if (SecStaticCodeCheckValidityWithErrors(staticCode,
|
||||
kSecCSBasicValidateOnly, sandboxRequirement, nullptr) != errSecSuccess)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}();
|
||||
return isSandboxed;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
@implementation NSObject (QtSandboxHelpers)
|
||||
- (id)qt_valueForPrivateKey:(NSString *)key
|
||||
{
|
||||
if (qt_apple_isSandboxed())
|
||||
return nil;
|
||||
|
||||
return [self valueForKey:key];
|
||||
}
|
||||
@end
|
||||
QT_BEGIN_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
/*
|
||||
Ensure that Objective-C objects auto-released in main(), directly or indirectly,
|
||||
|
@ -160,6 +160,17 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
|
||||
Q_CORE_EXPORT void qt_apple_check_os_version();
|
||||
Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
|
||||
|
||||
#if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED)
|
||||
Q_CORE_EXPORT bool qt_apple_isSandboxed();
|
||||
# ifdef __OBJC__
|
||||
QT_END_NAMESPACE
|
||||
@interface NSObject (QtSandboxHelpers)
|
||||
- (id)qt_valueForPrivateKey:(NSString *)key;
|
||||
@end
|
||||
QT_BEGIN_NAMESPACE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
|
||||
QT_END_NAMESPACE
|
||||
# if defined(Q_OS_MACOS)
|
||||
|
@ -1297,10 +1297,18 @@ void QGuiApplicationPrivate::createPlatformIntegration()
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
||||
QByteArray sessionType = qgetenv("XDG_SESSION_TYPE");
|
||||
if (!sessionType.isEmpty()) {
|
||||
if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb")))
|
||||
if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb"))) {
|
||||
platformName = QByteArrayLiteral("xcb");
|
||||
else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland")))
|
||||
platformName = QByteArrayLiteral("wayland");
|
||||
} else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland"))) {
|
||||
QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
|
||||
QByteArray sessionDesktop = qgetenv("XDG_SESSION_DESKTOP").toLower();
|
||||
if (currentDesktop.contains("gnome") || sessionDesktop.contains("gnome")) {
|
||||
qInfo() << "Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome."
|
||||
<< "Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.";
|
||||
} else {
|
||||
platformName = QByteArrayLiteral("wayland");
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
|
||||
// Add it as fallback in case XDG_SESSION_TYPE is something wrong
|
||||
|
@ -69,25 +69,38 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
|
||||
/*!
|
||||
Overridden to ensure that the zoomed state always results in a maximized
|
||||
window, which would otherwise not be the case for borderless windows.
|
||||
|
||||
We also keep the window on the same screen as before; something AppKit
|
||||
sometimes fails to do using its built in logic.
|
||||
*/
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)proposedFrame
|
||||
{
|
||||
Q_UNUSED(proposedFrame);
|
||||
Q_ASSERT(window == m_cocoaWindow->nativeWindow());
|
||||
|
||||
// We compute the maximized state based on the maximum size, and
|
||||
// the current position of the window. This may result in the window
|
||||
// geometry falling outside of the current screen's available geometry,
|
||||
// e.g. when there is not maximize size set, but this is okey, AppKit
|
||||
// will then shift and possibly clip the geometry for us.
|
||||
const QWindow *w = m_cocoaWindow->window();
|
||||
QRect maximizedRect = QRect(w->framePosition(), w->maximumSize());
|
||||
|
||||
// QWindow::maximumSize() refers to the client size,
|
||||
// but AppKit expects the full frame size.
|
||||
maximizedRect.adjust(0, 0, 0, w->frameMargins().top());
|
||||
// maximumSize() refers to the client size, but AppKit expects the full frame size
|
||||
QSizeF maximumSize = w->maximumSize() + QSize(0, w->frameMargins().top());
|
||||
|
||||
return QCocoaScreen::mapToNative(maximizedRect);
|
||||
// The window should never be larger than the current screen geometry
|
||||
const QRectF screenGeometry = m_cocoaWindow->screen()->geometry();
|
||||
maximumSize = maximumSize.boundedTo(screenGeometry.size());
|
||||
|
||||
// Use the current frame position for the initial maximized frame,
|
||||
// so that the window stays put and just expand, in case its maximum
|
||||
// size is within the screen bounds.
|
||||
QRectF maximizedFrame = QRectF(w->framePosition(), maximumSize);
|
||||
|
||||
// But constrain the frame to the screen bounds in case the frame
|
||||
// extends beyond the screen bounds as a result of starting out
|
||||
// with the current frame position.
|
||||
maximizedFrame.translate(QPoint(
|
||||
qMax(screenGeometry.left() - maximizedFrame.left(), 0.0) +
|
||||
qMin(screenGeometry.right() - maximizedFrame.right(), 0.0),
|
||||
qMax(screenGeometry.top() - maximizedFrame.top(), 0.0) +
|
||||
qMin(screenGeometry.bottom() - maximizedFrame.bottom(), 0.0)));
|
||||
|
||||
return QCocoaScreen::mapToNative(maximizedFrame);
|
||||
}
|
||||
|
||||
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
|
||||
|
@ -5,8 +5,6 @@ TARGET = qios
|
||||
# application's main() when the plugin is a shared library.
|
||||
qtConfig(shared): CONFIG += static
|
||||
|
||||
CONFIG += no_app_extension_api_only
|
||||
|
||||
QT += \
|
||||
core-private gui-private \
|
||||
clipboard_support-private fontdatabase_support-private graphics_support-private
|
||||
|
@ -86,7 +86,7 @@ static void qRegisterApplicationStateNotifications()
|
||||
QLatin1String("Extension loaded, assuming state is active"));
|
||||
} else {
|
||||
// Initialize correct startup state, which may not be the Qt default (inactive)
|
||||
UIApplicationState startupState = [UIApplication sharedApplication].applicationState;
|
||||
UIApplicationState startupState = qt_apple_sharedApplication().applicationState;
|
||||
QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application loaded"));
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterApplicationStateNotifications)
|
||||
QIOSApplicationState::QIOSApplicationState()
|
||||
{
|
||||
if (!qt_apple_isApplicationExtension()) {
|
||||
UIApplicationState startupState = [UIApplication sharedApplication].applicationState;
|
||||
UIApplicationState startupState = qt_apple_sharedApplication().applicationState;
|
||||
QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application launched"));
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include "qiosfiledialog.h"
|
||||
#include "qiosintegration.h"
|
||||
#include "qiosoptionalplugininterface.h"
|
||||
@ -94,7 +96,7 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
|
||||
}
|
||||
|
||||
UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
|
||||
: [UIApplication sharedApplication].keyWindow;
|
||||
: qt_apple_sharedApplication().keyWindow;
|
||||
[window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
|
||||
|
||||
return true;
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "qiosviewcontroller.h"
|
||||
#include "qiosscreen.h"
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
|
||||
@ -50,13 +52,16 @@ Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||
|
||||
bool isQtApplication()
|
||||
{
|
||||
if (qt_apple_isApplicationExtension())
|
||||
return false;
|
||||
|
||||
// Returns \c true if the plugin is in full control of the whole application. This means
|
||||
// that we control the application delegate and the top view controller, and can take
|
||||
// actions that impacts all parts of the application. The opposite means that we are
|
||||
// embedded inside a native iOS application, and should be more focused on playing along
|
||||
// with native UIControls, and less inclined to change structures that lies outside the
|
||||
// scope of our QWindows/UIViews.
|
||||
static bool isQt = ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]);
|
||||
static bool isQt = ([qt_apple_sharedApplication().delegate isKindOfClass:[QIOSApplicationDelegate class]]);
|
||||
return isQt;
|
||||
}
|
||||
|
||||
@ -152,8 +157,13 @@ QT_END_NAMESPACE
|
||||
|
||||
+ (id)currentFirstResponder
|
||||
{
|
||||
if (qt_apple_isApplicationExtension()) {
|
||||
qWarning() << "can't get first responder in application extensions!";
|
||||
return nil;
|
||||
}
|
||||
|
||||
QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease];
|
||||
[[UIApplication sharedApplication] sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
|
||||
[qt_apple_sharedApplication() sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
|
||||
return event.firstResponder;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,8 @@
|
||||
#include "qioswindow.h"
|
||||
#include "quiview.h"
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QtGui/private/qwindow_p.h>
|
||||
|
||||
@ -536,6 +538,11 @@ void QIOSInputContext::scroll(int y)
|
||||
if (!rootView)
|
||||
return;
|
||||
|
||||
if (qt_apple_isApplicationExtension()) {
|
||||
qWarning() << "can't scroll root view in application extension";
|
||||
return;
|
||||
}
|
||||
|
||||
CATransform3D translationTransform = CATransform3DMakeTranslation(0.0, -y, 0.0);
|
||||
if (CATransform3DEqualToTransform(translationTransform, rootView.layer.sublayerTransform))
|
||||
return;
|
||||
@ -574,7 +581,7 @@ void QIOSInputContext::scroll(int y)
|
||||
|
||||
// Raise all known windows to above the status-bar if we're scrolling the screen,
|
||||
// while keeping the relative window level between the windows the same.
|
||||
NSArray *applicationWindows = [[UIApplication sharedApplication] windows];
|
||||
NSArray *applicationWindows = [qt_apple_sharedApplication() windows];
|
||||
static QHash<UIWindow *, UIWindowLevel> originalWindowLevels;
|
||||
for (UIWindow *window in applicationWindows) {
|
||||
if (keyboardScrollIsActive && !originalWindowLevels.contains(window))
|
||||
|
@ -86,7 +86,7 @@ QIOSIntegration::QIOSIntegration()
|
||||
, m_accessibility(0)
|
||||
, m_optionalPlugins(new QFactoryLoader(QIosOptionalPluginInterface_iid, QLatin1String("/platforms/darwin")))
|
||||
{
|
||||
if (Q_UNLIKELY(![UIApplication sharedApplication])) {
|
||||
if (Q_UNLIKELY(!qt_apple_isApplicationExtension() && !qt_apple_sharedApplication())) {
|
||||
qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n" \
|
||||
"If you are writing a native iOS application, and only want to use Qt for\n" \
|
||||
"parts of the application, a good place to create QApplication is from within\n" \
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include "qiosglobal.h"
|
||||
#include "quiview.h"
|
||||
#include "qiosmessagedialog.h"
|
||||
@ -126,7 +128,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win
|
||||
[m_alertController addAction:createAction(NoButton)];
|
||||
}
|
||||
|
||||
UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window : [UIApplication sharedApplication].keyWindow;
|
||||
UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window : qt_apple_sharedApplication().keyWindow;
|
||||
[window.rootViewController presentViewController:m_alertController animated:YES completion:nil];
|
||||
return true;
|
||||
}
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "qiosviewcontroller.h"
|
||||
#include "quiview.h"
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QtGui/private/qwindow_p.h>
|
||||
#include <private/qcoregraphics_p.h>
|
||||
|
||||
@ -271,17 +273,19 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
|
||||
m_physicalDpi = 96;
|
||||
}
|
||||
|
||||
for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
|
||||
if (existingWindow.screen == m_uiScreen) {
|
||||
m_uiWindow = [m_uiWindow retain];
|
||||
break;
|
||||
if (!qt_apple_isApplicationExtension()) {
|
||||
for (UIWindow *existingWindow in qt_apple_sharedApplication().windows) {
|
||||
if (existingWindow.screen == m_uiScreen) {
|
||||
m_uiWindow = [m_uiWindow retain];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_uiWindow) {
|
||||
// Create a window and associated view-controller that we can use
|
||||
m_uiWindow = [[QUIWindow alloc] initWithFrame:[m_uiScreen bounds]];
|
||||
m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
|
||||
if (!m_uiWindow) {
|
||||
// Create a window and associated view-controller that we can use
|
||||
m_uiWindow = [[QUIWindow alloc] initWithFrame:[m_uiScreen bounds]];
|
||||
m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
updateProperties();
|
||||
@ -327,17 +331,20 @@ void QIOSScreen::updateProperties()
|
||||
|
||||
#ifndef Q_OS_TVOS
|
||||
if (m_uiScreen == [UIScreen mainScreen]) {
|
||||
Qt::ScreenOrientation statusBarOrientation = toQtScreenOrientation(UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation));
|
||||
|
||||
QIOSViewController *qtViewController = [m_uiWindow.rootViewController isKindOfClass:[QIOSViewController class]] ?
|
||||
static_cast<QIOSViewController *>(m_uiWindow.rootViewController) : nil;
|
||||
|
||||
if (qtViewController.lockedOrientation) {
|
||||
Q_ASSERT(!qt_apple_isApplicationExtension());
|
||||
|
||||
// Setting the statusbar orientation (content orientation) on will affect the screen geometry,
|
||||
// which is not what we want. We want to reflect the screen geometry based on the locked orientation,
|
||||
// and adjust the available geometry based on the repositioned status bar for the current status
|
||||
// bar orientation.
|
||||
|
||||
Qt::ScreenOrientation statusBarOrientation = toQtScreenOrientation(
|
||||
UIDeviceOrientation(qt_apple_sharedApplication().statusBarOrientation));
|
||||
|
||||
Qt::ScreenOrientation lockedOrientation = toQtScreenOrientation(UIDeviceOrientation(qtViewController.lockedOrientation));
|
||||
QTransform transform = transformBetween(lockedOrientation, statusBarOrientation, m_geometry).inverted();
|
||||
|
||||
@ -487,8 +494,8 @@ Qt::ScreenOrientation QIOSScreen::orientation() const
|
||||
// the orientation the application was started up in (which may not match
|
||||
// the physical orientation of the device, but typically does unless the
|
||||
// application has been locked to a subset of the available orientations).
|
||||
if (deviceOrientation == UIDeviceOrientationUnknown)
|
||||
deviceOrientation = UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation);
|
||||
if (deviceOrientation == UIDeviceOrientationUnknown && !qt_apple_isApplicationExtension())
|
||||
deviceOrientation = UIDeviceOrientation(qt_apple_sharedApplication().statusBarOrientation);
|
||||
|
||||
// If the device reports face up or face down orientations, we can't map
|
||||
// them to Qt orientations, so we pretend we're in the same orientation
|
||||
|
@ -40,6 +40,9 @@
|
||||
#include "qiosservices.h"
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QtGui/qdesktopservices.h>
|
||||
|
||||
#import <UIKit/UIApplication.h>
|
||||
@ -48,6 +51,11 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
bool QIOSServices::openUrl(const QUrl &url)
|
||||
{
|
||||
if (qt_apple_isApplicationExtension()) {
|
||||
qWarning() << "openUrl not implement for application extensions yet";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url == m_handlingUrl)
|
||||
return false;
|
||||
|
||||
@ -55,12 +63,25 @@ bool QIOSServices::openUrl(const QUrl &url)
|
||||
return openDocument(url);
|
||||
|
||||
NSURL *nsUrl = url.toNSURL();
|
||||
UIApplication *application = [UIApplication sharedApplication];
|
||||
UIApplication *application = qt_apple_sharedApplication();
|
||||
|
||||
if (![application canOpenURL:nsUrl])
|
||||
return false;
|
||||
|
||||
[application openURL:nsUrl options:@{} completionHandler:nil];
|
||||
static SEL openUrlSelector = @selector(openURL:options:completionHandler:);
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
|
||||
[UIApplication instanceMethodSignatureForSelector:openUrlSelector]];
|
||||
invocation.target = application;
|
||||
invocation.selector = openUrlSelector;
|
||||
|
||||
static auto kEmptyDictionary = @{};
|
||||
// Indices 0 and 1 are self and _cmd
|
||||
[invocation setArgument:&nsUrl atIndex:2];
|
||||
[invocation setArgument:&kEmptyDictionary atIndex:3];
|
||||
// Fourth argument is nil, so left unset
|
||||
|
||||
[invocation invoke];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@
|
||||
|
||||
#include <QtGui/private/qinputmethod_p.h>
|
||||
#include <QtCore/private/qobject_p.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include "qiosglobal.h"
|
||||
#include "qiostextinputoverlay.h"
|
||||
@ -475,7 +476,7 @@ static void executeBlockWithoutAnimation(Block block)
|
||||
|
||||
if (enabled) {
|
||||
_focusView = [reinterpret_cast<UIView *>(qApp->focusWindow()->winId()) retain];
|
||||
_desktopView = [[UIApplication sharedApplication].keyWindow.rootViewController.view retain];
|
||||
_desktopView = [qt_apple_sharedApplication().keyWindow.rootViewController.view retain];
|
||||
Q_ASSERT(_focusView && _desktopView && _desktopView.superview);
|
||||
[_desktopView addGestureRecognizer:self];
|
||||
} else {
|
||||
@ -991,6 +992,11 @@ QIOSTextInputOverlay::QIOSTextInputOverlay()
|
||||
, m_selectionRecognizer(nullptr)
|
||||
, m_openMenuOnTapRecognizer(nullptr)
|
||||
{
|
||||
if (qt_apple_isApplicationExtension()) {
|
||||
qWarning() << "text input overlays disabled in application extensions";
|
||||
return;
|
||||
}
|
||||
|
||||
connect(qApp, &QGuiApplication::focusObjectChanged, this, &QIOSTextInputOverlay::updateFocusObject);
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QtGui/QFont>
|
||||
|
||||
@ -103,7 +104,7 @@ bool QIOSTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
|
||||
switch (type) {
|
||||
case FileDialog:
|
||||
case MessageDialog:
|
||||
return true;
|
||||
return !qt_apple_isApplicationExtension();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#import "qiosviewcontroller.h"
|
||||
|
||||
#include <QtCore/qscopedvaluerollback.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QWindow>
|
||||
@ -307,15 +308,17 @@
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
Q_ASSERT(!qt_apple_isApplicationExtension());
|
||||
|
||||
#ifndef Q_OS_TVOS
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:self selector:@selector(willChangeStatusBarFrame:)
|
||||
name:UIApplicationWillChangeStatusBarFrameNotification
|
||||
object:[UIApplication sharedApplication]];
|
||||
object:qt_apple_sharedApplication()];
|
||||
|
||||
[center addObserver:self selector:@selector(didChangeStatusBarOrientation:)
|
||||
name:UIApplicationDidChangeStatusBarOrientationNotification
|
||||
object:[UIApplication sharedApplication]];
|
||||
object:qt_apple_sharedApplication()];
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -455,7 +458,6 @@
|
||||
focusWindow = qt_window_private(focusWindow)->topLevelWindow();
|
||||
|
||||
#ifndef Q_OS_TVOS
|
||||
UIApplication *uiApplication = [UIApplication sharedApplication];
|
||||
|
||||
// -------------- Status bar style and visbility ---------------
|
||||
|
||||
@ -479,6 +481,8 @@
|
||||
|
||||
// -------------- Content orientation ---------------
|
||||
|
||||
UIApplication *uiApplication = qt_apple_sharedApplication();
|
||||
|
||||
static BOOL kAnimateContentOrientationChanges = YES;
|
||||
|
||||
Qt::ScreenOrientation contentOrientation = focusWindow->contentOrientation();
|
||||
|
@ -95,6 +95,9 @@ public:
|
||||
void put(xcb_drawable_t dst, const QRegion ®ion, const QPoint &offset);
|
||||
void preparePaint(const QRegion ®ion);
|
||||
|
||||
static bool createSystemVShmSegment(QXcbConnection *c, size_t segmentSize = 1,
|
||||
xcb_shm_segment_info_t *shm_info = nullptr);
|
||||
|
||||
private:
|
||||
void createShmSegment(size_t segmentSize);
|
||||
void destroyShmSegment(size_t segmentSize);
|
||||
@ -325,15 +328,16 @@ void QXcbBackingStoreImage::createShmSegment(size_t segmentSize)
|
||||
#ifdef XCB_USE_SHM_FD
|
||||
if (connection()->hasShmFd()) {
|
||||
if (Q_UNLIKELY(segmentSize > std::numeric_limits<uint32_t>::max())) {
|
||||
qWarning("QXcbShmImage: xcb_shm_create_segment() can't be called for size %zu, maximum allowed size is %u",
|
||||
segmentSize, std::numeric_limits<uint32_t>::max());
|
||||
qCWarning(lcQpaXcb, "xcb_shm_create_segment() can't be called for size %zu, maximum"
|
||||
"allowed size is %u", segmentSize, std::numeric_limits<uint32_t>::max());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto seg = xcb_generate_id(xcb_connection());
|
||||
auto reply = Q_XCB_REPLY(xcb_shm_create_segment,
|
||||
xcb_connection(), seg, segmentSize, false);
|
||||
if (!reply) {
|
||||
qWarning("QXcbShmImage: xcb_shm_create_segment() failed for size %zu", segmentSize);
|
||||
qCWarning(lcQpaXcb, "xcb_shm_create_segment() failed for size %zu", segmentSize);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -342,13 +346,13 @@ void QXcbBackingStoreImage::createShmSegment(size_t segmentSize)
|
||||
for (int i = 0; i < reply->nfd; i++)
|
||||
close(fds[i]);
|
||||
|
||||
qWarning("QXcbShmImage: failed to get file descriptor for shm segment of size %zu", segmentSize);
|
||||
qCWarning(lcQpaXcb, "failed to get file descriptor for shm segment of size %zu", segmentSize);
|
||||
return;
|
||||
}
|
||||
|
||||
void *addr = mmap(nullptr, segmentSize, PROT_READ|PROT_WRITE, MAP_SHARED, fds[0], 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
qWarning("QXcbShmImage: failed to mmap segment from X server (%d: %s) for size %zu",
|
||||
qCWarning(lcQpaXcb, "failed to mmap segment from X server (%d: %s) for size %zu",
|
||||
errno, strerror(errno), segmentSize);
|
||||
close(fds[0]);
|
||||
xcb_shm_detach(xcb_connection(), seg);
|
||||
@ -358,49 +362,56 @@ void QXcbBackingStoreImage::createShmSegment(size_t segmentSize)
|
||||
close(fds[0]);
|
||||
m_shm_info.shmseg = seg;
|
||||
m_shm_info.shmaddr = static_cast<quint8 *>(addr);
|
||||
|
||||
m_segmentSize = segmentSize;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
const int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
|
||||
if (id == -1) {
|
||||
qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %zu",
|
||||
errno, strerror(errno), segmentSize);
|
||||
return;
|
||||
}
|
||||
|
||||
void *addr = shmat(id, 0, 0);
|
||||
if (addr == (void *)-1) {
|
||||
qWarning("QXcbShmImage: shmat() failed (%d: %s) for id %d",
|
||||
errno, strerror(errno), id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shmctl(id, IPC_RMID, 0) == -1)
|
||||
qWarning("QXcbBackingStore: Error while marking the shared memory segment to be destroyed");
|
||||
|
||||
const auto seg = xcb_generate_id(xcb_connection());
|
||||
auto cookie = xcb_shm_attach_checked(xcb_connection(), seg, id, false);
|
||||
auto *error = xcb_request_check(xcb_connection(), cookie);
|
||||
if (error) {
|
||||
connection()->printXcbError("QXcbShmImage: xcb_shm_attach() failed with error", error);
|
||||
free(error);
|
||||
if (shmdt(addr) == -1) {
|
||||
qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p",
|
||||
errno, strerror(errno), addr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_shm_info.shmseg = seg;
|
||||
m_shm_info.shmid = id; // unused
|
||||
m_shm_info.shmaddr = static_cast<quint8 *>(addr);
|
||||
|
||||
m_segmentSize = segmentSize;
|
||||
if (createSystemVShmSegment(connection(), segmentSize, &m_shm_info))
|
||||
m_segmentSize = segmentSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool QXcbBackingStoreImage::createSystemVShmSegment(QXcbConnection *c, size_t segmentSize,
|
||||
xcb_shm_segment_info_t *shmInfo)
|
||||
{
|
||||
const int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
|
||||
if (id == -1) {
|
||||
qCWarning(lcQpaXcb, "shmget() failed (%d: %s) for size %zu", errno, strerror(errno), segmentSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
void *addr = shmat(id, 0, 0);
|
||||
if (addr == (void *)-1) {
|
||||
qCWarning(lcQpaXcb, "shmat() failed (%d: %s) for id %d", errno, strerror(errno), id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shmctl(id, IPC_RMID, 0) == -1)
|
||||
qCWarning(lcQpaXcb, "Error while marking the shared memory segment to be destroyed");
|
||||
|
||||
const auto seg = xcb_generate_id(c->xcb_connection());
|
||||
auto cookie = xcb_shm_attach_checked(c->xcb_connection(), seg, id, false);
|
||||
auto *error = xcb_request_check(c->xcb_connection(), cookie);
|
||||
if (error) {
|
||||
c->printXcbError("xcb_shm_attach() failed with error", error);
|
||||
free(error);
|
||||
if (shmdt(addr) == -1)
|
||||
qCWarning(lcQpaXcb, "shmdt() failed (%d: %s) for %p", errno, strerror(errno), addr);
|
||||
return false;
|
||||
} else if (!shmInfo) { // this was a test run, free the allocated test segment
|
||||
xcb_shm_detach(c->xcb_connection(), seg);
|
||||
auto shmaddr = static_cast<quint8 *>(addr);
|
||||
if (shmdt(shmaddr) == -1)
|
||||
qCWarning(lcQpaXcb, "shmdt() failed (%d: %s) for %p", errno, strerror(errno), shmaddr);
|
||||
}
|
||||
if (shmInfo) {
|
||||
shmInfo->shmseg = seg;
|
||||
shmInfo->shmid = id; // unused
|
||||
shmInfo->shmaddr = static_cast<quint8 *>(addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
|
||||
{
|
||||
#ifndef XCB_USE_SHM_FD
|
||||
@ -409,21 +420,21 @@ void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
|
||||
auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg);
|
||||
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
|
||||
if (error)
|
||||
connection()->printXcbError("QXcbShmImage: xcb_shm_detach() failed with error", error);
|
||||
connection()->printXcbError("xcb_shm_detach() failed with error", error);
|
||||
m_shm_info.shmseg = 0;
|
||||
|
||||
#ifdef XCB_USE_SHM_FD
|
||||
if (connection()->hasShmFd()) {
|
||||
if (munmap(m_shm_info.shmaddr, segmentSize) == -1) {
|
||||
qWarning("QXcbShmImage: munmap() failed (%d: %s) for %p with size %zu",
|
||||
errno, strerror(errno), m_shm_info.shmaddr, segmentSize);
|
||||
qCWarning(lcQpaXcb, "munmap() failed (%d: %s) for %p with size %zu",
|
||||
errno, strerror(errno), m_shm_info.shmaddr, segmentSize);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (shmdt(m_shm_info.shmaddr) == -1) {
|
||||
qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p",
|
||||
errno, strerror(errno), m_shm_info.shmaddr);
|
||||
qCWarning(lcQpaXcb, "shmdt() failed (%d: %s) for %p",
|
||||
errno, strerror(errno), m_shm_info.shmaddr);
|
||||
}
|
||||
m_shm_info.shmid = 0; // unused
|
||||
}
|
||||
@ -718,6 +729,12 @@ void QXcbBackingStoreImage::preparePaint(const QRegion ®ion)
|
||||
m_pendingFlush |= region;
|
||||
}
|
||||
|
||||
bool QXcbBackingStore::createSystemVShmSegment(QXcbConnection *c, size_t segmentSize, void *shmInfo)
|
||||
{
|
||||
auto info = reinterpret_cast<xcb_shm_segment_info_t *>(shmInfo);
|
||||
return QXcbBackingStoreImage::createSystemVShmSegment(c, segmentSize, info);
|
||||
}
|
||||
|
||||
QXcbBackingStore::QXcbBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
{
|
||||
@ -757,7 +774,7 @@ void QXcbBackingStore::beginPaint(const QRegion ®ion)
|
||||
void QXcbBackingStore::endPaint()
|
||||
{
|
||||
if (Q_UNLIKELY(m_paintRegions.isEmpty())) {
|
||||
qWarning("%s: paint regions empty!", Q_FUNC_INFO);
|
||||
qCWarning(lcQpaXcb, "%s: paint regions empty!", Q_FUNC_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -811,7 +828,7 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin
|
||||
|
||||
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
|
||||
if (!platformWindow) {
|
||||
qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
|
||||
qCWarning(lcQpaXcb, "%s QWindow has no platform window, see QTBUG-32681", Q_FUNC_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
void beginPaint(const QRegion &) override;
|
||||
void endPaint() override;
|
||||
|
||||
static bool createSystemVShmSegment(QXcbConnection *c, size_t segmentSize = 1,
|
||||
void *shmInfo = nullptr);
|
||||
|
||||
private:
|
||||
QXcbBackingStoreImage *m_image = nullptr;
|
||||
QStack<QRegion> m_paintRegions;
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "qxcbsystemtraytracker.h"
|
||||
#include "qxcbglintegrationfactory.h"
|
||||
#include "qxcbglintegration.h"
|
||||
#include "qxcbbackingstore.h"
|
||||
|
||||
#include <QSocketNotifier>
|
||||
#include <QAbstractEventDispatcher>
|
||||
@ -585,7 +586,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
|
||||
initializeAllAtoms();
|
||||
|
||||
initializeShm();
|
||||
if (!qEnvironmentVariableIsSet("QT_XCB_NO_MITSHM"))
|
||||
initializeShm();
|
||||
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
|
||||
initializeXRandr();
|
||||
if (!has_randr_extension)
|
||||
@ -973,7 +975,7 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
|
||||
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
|
||||
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
|
||||
|
||||
qWarning("%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
|
||||
qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
|
||||
message,
|
||||
int(error->error_code), xcb_errors[clamped_error_code],
|
||||
int(error->sequence), int(error->resource_id),
|
||||
@ -1683,12 +1685,14 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
|
||||
if (!hasXInput2())
|
||||
return false;
|
||||
|
||||
// compress XI_Motion, but not from tablet devices
|
||||
// compress XI_Motion
|
||||
if (isXIType(event, m_xiOpCode, XI_Motion)) {
|
||||
#if QT_CONFIG(tabletevent)
|
||||
xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||
// Xlib's XI2 events need memmove, see xi2PrepareXIGenericDeviceEvent()
|
||||
auto sourceId = *reinterpret_cast<uint16_t *>(reinterpret_cast<char *>(&xdev->sourceid) + 4);
|
||||
if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) &&
|
||||
const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
|
||||
const_cast<QXcbConnection *>(this)->tabletDataForDevice(sourceId))
|
||||
return false;
|
||||
#endif // QT_CONFIG(tabletevent)
|
||||
for (int j = nextIndex; j < eventqueue->size(); ++j) {
|
||||
@ -2101,20 +2105,34 @@ void QXcbConnection::initializeShm()
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_shm_id);
|
||||
if (!reply || !reply->present) {
|
||||
qWarning("QXcbConnection: MIT-SHM extension is not present on the X server.");
|
||||
qCDebug(lcQpaXcb, "MIT-SHM extension is not present on the X server");
|
||||
return;
|
||||
}
|
||||
|
||||
has_shm = true;
|
||||
|
||||
auto shm_query = Q_XCB_REPLY(xcb_shm_query_version, m_connection);
|
||||
if (!shm_query) {
|
||||
qWarning("QXcbConnection: Failed to request MIT-SHM version");
|
||||
return;
|
||||
if (shm_query) {
|
||||
has_shm_fd = (shm_query->major_version == 1 && shm_query->minor_version >= 2) ||
|
||||
shm_query->major_version > 1;
|
||||
} else {
|
||||
qCWarning(lcQpaXcb, "QXcbConnection: Failed to request MIT-SHM version");
|
||||
}
|
||||
|
||||
has_shm_fd = (shm_query->major_version == 1 && shm_query->minor_version >= 2) ||
|
||||
shm_query->major_version > 1;
|
||||
qCDebug(lcQpaXcb) << "Has MIT-SHM :" << has_shm;
|
||||
qCDebug(lcQpaXcb) << "Has MIT-SHM FD :" << has_shm_fd;
|
||||
|
||||
// Temporary disable warnings (unless running in debug mode).
|
||||
auto logging = const_cast<QLoggingCategory*>(&lcQpaXcb());
|
||||
bool wasEnabled = logging->isEnabled(QtMsgType::QtWarningMsg);
|
||||
if (!logging->isEnabled(QtMsgType::QtDebugMsg))
|
||||
logging->setEnabled(QtMsgType::QtWarningMsg, false);
|
||||
if (!QXcbBackingStore::createSystemVShmSegment(this)) {
|
||||
qCDebug(lcQpaXcb, "failed to create System V shared memory segment (remote "
|
||||
"X11 connection?), disabling SHM");
|
||||
has_shm = has_shm_fd = false;
|
||||
}
|
||||
if (wasEnabled)
|
||||
logging->setEnabled(QtMsgType::QtWarningMsg, true);
|
||||
}
|
||||
|
||||
void QXcbConnection::initializeXFixes()
|
||||
|
@ -750,12 +750,7 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
|
||||
m_sizeMillimeters = sizeInMillimeters(geometry.size(), virtualDpi());
|
||||
|
||||
qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
|
||||
qreal rawFactor = dpi/96;
|
||||
int roundedFactor = qFloor(rawFactor);
|
||||
// Round up for .8 and higher. This favors "small UI" over "large UI".
|
||||
if (rawFactor - roundedFactor >= 0.8)
|
||||
roundedFactor = qCeil(rawFactor);
|
||||
m_pixelDensity = qMax(1, roundedFactor);
|
||||
m_pixelDensity = qMax(1, qRound(dpi/96));
|
||||
m_geometry = geometry;
|
||||
m_availableGeometry = geometry & m_virtualDesktop->workArea();
|
||||
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
|
||||
|
@ -248,24 +248,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QVerticalSplitView);
|
||||
}
|
||||
@end
|
||||
|
||||
#if !QT_CONFIG(appstore_compliant)
|
||||
|
||||
// This API was requested to Apple in rdar #36197888.
|
||||
// We know it's safe to use up to macOS 10.13.3.
|
||||
// See drawComplexControl(CC_ComboBox) for its usage.
|
||||
|
||||
@interface NSComboBoxCell (QtButtonCell)
|
||||
@property (readonly) NSButtonCell *qt_buttonCell;
|
||||
@end
|
||||
|
||||
@implementation NSComboBoxCell (QtButtonCell)
|
||||
- (NSButtonCell *)qt_buttonCell {
|
||||
return self->_buttonCell;
|
||||
}
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// The following constants are used for adjusting the size
|
||||
@ -5215,11 +5197,14 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
auto *cb = static_cast<NSComboBox *>(cc);
|
||||
const auto frameRect = cw.adjustedControlFrame(combo->rect);
|
||||
cb.frame = frameRect.toCGRect();
|
||||
#if !QT_CONFIG(appstore_compliant)
|
||||
static_cast<NSComboBoxCell *>(cc.cell).qt_buttonCell.highlighted = isPressed;
|
||||
#else
|
||||
// TODO Render to pixmap and darken the button manually
|
||||
#endif
|
||||
|
||||
// This API was requested to Apple in rdar #36197888. We know it's safe to use up to macOS 10.13.3
|
||||
if (NSButtonCell *cell = static_cast<NSButtonCell *>([cc.cell qt_valueForPrivateKey:@"_buttonCell"])) {
|
||||
cell.highlighted = isPressed;
|
||||
} else {
|
||||
// TODO Render to pixmap and darken the button manually
|
||||
}
|
||||
|
||||
d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
// FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case
|
||||
[cb.cell drawWithFrame:r inView:cb];
|
||||
|
@ -1579,6 +1579,7 @@ QGraphicsItem::~QGraphicsItem()
|
||||
QObjectPrivate *p = QObjectPrivate::get(o);
|
||||
p->wasDeleted = true;
|
||||
if (p->declarativeData) {
|
||||
p->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
|
||||
if (static_cast<QAbstractDeclarativeDataImpl*>(p->declarativeData)->ownedByQml1) {
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(p->declarativeData, o);
|
||||
@ -1587,6 +1588,7 @@ QGraphicsItem::~QGraphicsItem()
|
||||
QAbstractDeclarativeData::destroyed(p->declarativeData, o);
|
||||
}
|
||||
p->declarativeData = 0;
|
||||
p->wasDeleted = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2725,7 +2725,7 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
|
||||
statusTip = d->model->headerData(logical, d->orientation, Qt::StatusTipRole).toString();
|
||||
if (d->shouldClearStatusTip || !statusTip.isEmpty()) {
|
||||
QStatusTipEvent tip(statusTip);
|
||||
QCoreApplication::sendEvent(d->parent, &tip);
|
||||
QCoreApplication::sendEvent(d->parent ? d->parent : this, &tip);
|
||||
d->shouldClearStatusTip = !statusTip.isEmpty();
|
||||
}
|
||||
#endif // !QT_NO_STATUSTIP
|
||||
|
@ -1677,8 +1677,8 @@ QWidget::~QWidget()
|
||||
}
|
||||
}
|
||||
|
||||
d->wasDeleted = true;
|
||||
if (d->declarativeData) {
|
||||
d->wasDeleted = true; // needed, so that destroying the declarative data does the right thing
|
||||
if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
|
||||
@ -1687,6 +1687,7 @@ QWidget::~QWidget()
|
||||
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
|
||||
}
|
||||
d->declarativeData = 0; // don't activate again in ~QObject
|
||||
d->wasDeleted = false;
|
||||
}
|
||||
|
||||
d->blockSig = blocked;
|
||||
|
@ -47,6 +47,7 @@ find_package(Qt5Core REQUIRED)
|
||||
|
||||
include("${_Qt5CTestMacros}")
|
||||
|
||||
expect_pass(test_use_modules_function)
|
||||
expect_pass(test_umbrella_config)
|
||||
expect_pass(test_wrap_cpp_and_resources)
|
||||
if (NOT NO_WIDGETS)
|
||||
|
18
tests/auto/cmake/test_use_modules_function/CMakeLists.txt
Normal file
18
tests/auto/cmake/test_use_modules_function/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(test_use_modules_function)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_executable(two two.cpp)
|
||||
add_executable(three three.cpp)
|
||||
|
||||
find_package(Qt5Core)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
|
||||
|
||||
qt5_use_modules(two Test)
|
||||
qt5_use_modules(three Gui Test)
|
45
tests/auto/cmake/test_use_modules_function/three.cpp
Normal file
45
tests/auto/cmake/test_use_modules_function/three.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest>
|
||||
#include <QWindow>
|
||||
|
||||
class Three : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Three(QObject *parent = 0)
|
||||
{
|
||||
QWindow *w = new QWindow;
|
||||
w->show();
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(Three)
|
||||
|
||||
#include "three.moc"
|
43
tests/auto/cmake/test_use_modules_function/two.cpp
Normal file
43
tests/auto/cmake/test_use_modules_function/two.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
class Two : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Two(QObject *parent = 0)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(Two)
|
||||
|
||||
#include "two.moc"
|
@ -43,6 +43,7 @@
|
||||
#include <qtreewidget.h>
|
||||
#include <qdebug.h>
|
||||
#include <qscreen.h>
|
||||
#include <qdesktopwidget.h>
|
||||
|
||||
typedef QList<int> IntList;
|
||||
|
||||
@ -243,7 +244,7 @@ private slots:
|
||||
void testMinMaxSectionSize_data();
|
||||
void testMinMaxSectionSize();
|
||||
void sizeHintCrash();
|
||||
|
||||
void statusTips();
|
||||
protected:
|
||||
void setupTestData(bool use_reset_model = false);
|
||||
void additionalInit();
|
||||
@ -269,7 +270,19 @@ public:
|
||||
int rowCount(const QModelIndex&) const { return rows; }
|
||||
int columnCount(const QModelIndex&) const { return cols; }
|
||||
bool isEditable(const QModelIndex &) const { return true; }
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
|
||||
{
|
||||
if (section < 0 || (role != Qt::DisplayRole && role != Qt::StatusTipRole))
|
||||
return QVariant();
|
||||
const int row = (orientation == Qt::Vertical ? section : 0);
|
||||
const int col = (orientation == Qt::Horizontal ? section : 0);
|
||||
if (orientation == Qt::Vertical && row >= rows)
|
||||
return QVariant();
|
||||
if (orientation == Qt::Horizontal && col >= cols)
|
||||
return QVariant();
|
||||
return QLatin1Char('[') + QString::number(row) + QLatin1Char(',')
|
||||
+ QString::number(col) + QLatin1String(",0] -- Header");
|
||||
}
|
||||
QVariant data(const QModelIndex &idx, int) const
|
||||
{
|
||||
if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
|
||||
@ -3325,6 +3338,54 @@ void tst_QHeaderView::testMinMaxSectionSize()
|
||||
QTRY_COMPARE(header.sectionSize(0), defaultSectionSize);
|
||||
}
|
||||
|
||||
class StatusTipHeaderView : public QHeaderView
|
||||
{
|
||||
public:
|
||||
StatusTipHeaderView(Qt::Orientation orientation = Qt::Horizontal, QWidget *parent = 0) :
|
||||
QHeaderView(orientation, parent), gotStatusTipEvent(false) {}
|
||||
bool gotStatusTipEvent;
|
||||
QString statusTipText;
|
||||
protected:
|
||||
bool event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::StatusTip) {
|
||||
gotStatusTipEvent = true;
|
||||
statusTipText = static_cast<QStatusTipEvent *>(e)->tip();
|
||||
}
|
||||
return QHeaderView::event(e);
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QHeaderView::statusTips()
|
||||
{
|
||||
StatusTipHeaderView headerView;
|
||||
QtTestModel model;
|
||||
model.rows = model.cols = 5;
|
||||
headerView.setModel(&model);
|
||||
headerView.viewport()->setMouseTracking(true);
|
||||
headerView.setGeometry(QRect(QPoint(QApplication::desktop()->geometry().center() - QPoint(250, 250)),
|
||||
QSize(500, 500)));
|
||||
headerView.show();
|
||||
qApp->setActiveWindow(&headerView);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&headerView));
|
||||
|
||||
// Ensure it is moved away first and then moved to the relevant section
|
||||
QTest::mouseMove(QApplication::desktop(),
|
||||
headerView.rect().bottomLeft() + QPoint(20, 20));
|
||||
QPoint centerPoint = QRect(headerView.sectionPosition(0), headerView.y(),
|
||||
headerView.sectionSize(0), headerView.height()).center();
|
||||
QTest::mouseMove(headerView.windowHandle(), centerPoint);
|
||||
QTRY_VERIFY(headerView.gotStatusTipEvent);
|
||||
QCOMPARE(headerView.statusTipText, QLatin1String("[0,0,0] -- Header"));
|
||||
|
||||
headerView.gotStatusTipEvent = false;
|
||||
headerView.statusTipText.clear();
|
||||
centerPoint = QRect(headerView.sectionPosition(1), headerView.y(),
|
||||
headerView.sectionSize(1), headerView.height()).center();
|
||||
QTest::mouseMove(headerView.windowHandle(), centerPoint);
|
||||
QTRY_VERIFY(headerView.gotStatusTipEvent);
|
||||
QCOMPARE(headerView.statusTipText, QLatin1String("[0,1,0] -- Header"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHeaderView)
|
||||
#include "tst_qheaderview.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user