Merge remote-tracking branch 'origin/5.11.1' into 5.11

Change-Id: I9a4571ccf826a86e055dfbba23b5e5cbd8ea55e8
This commit is contained in:
Qt Forward Merge Bot 2018-06-19 13:12:48 +02:00
commit 8eabb44f8a
35 changed files with 663 additions and 209 deletions

144
dist/changes-5.11.1 vendored Normal file
View 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.

View File

@ -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>

View File

@ -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");

View File

@ -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()

View File

@ -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__

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"));
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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))

View File

@ -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" \

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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();

View File

@ -95,6 +95,9 @@ public:
void put(xcb_drawable_t dst, const QRegion &region, const QPoint &offset);
void preparePaint(const QRegion &region);
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 &region)
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 &region)
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 &region, 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;
}

View File

@ -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;

View File

@ -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()

View File

@ -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);

View File

@ -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];

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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)

View 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)

View 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"

View 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"

View File

@ -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"