Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev

This commit is contained in:
Frederik Gladhorn 2013-04-30 09:33:19 +02:00 committed by The Qt Project
commit c917579a15
165 changed files with 2296 additions and 1104 deletions

3
configure vendored
View File

@ -6947,5 +6947,6 @@ else
echo Qt will be installed into $QT_INSTALL_PREFIX
fi
echo
echo To reconfigure, run \'$MAKE confclean\' and \'configure\'.
echo Prior to reconfiguration, make sure you remove any leftovers from
echo the previous build.
echo

35
dist/README vendored
View File

@ -58,11 +58,12 @@ Directory Structure
-------------------
The default top-level installation directory is the directory "Qt<version>" in
your home directory, but you can specify another directory (<install_dir>). Each
Qt version is installed in the <install_dir>/<version> directory. This
directory contains subdirectories for the Qt libraries (<compiler>),
documentation (doc), and sources (src). The <compiler> directory contains
subdirectories for development tools (bin) and examples.
your home directory, but you can specify another directory (<install_dir>). On
Windows, however, the default top-level installation directory is "C:\Qt\Qt<version>".
Each Qt version is installed in the <install_dir>/<version> directory. This directory
contains subdirectories for the Qt libraries (<compiler>) and sources (Src).
The <compiler> directory contains subdirectories for development tools (bin) and
examples.
Starting Development Tools
@ -80,25 +81,21 @@ the command line. You can also launch some of them as standalone applications.
For example:
- Qt Assistant, the Qt documentation reader
- qmlscene, the viewer for Qt Quick2 declarative QML applications
- QMLViewer, the viewer for Qt Quick1 declarative QML applications
- Qt Designer, the GUI designer for Qt widgets-based applications
- Qt QML Scene, the viewer for Qt Quick 2 files
- Qt QML Viewer, the viewer for Qt Quick 1 files
and - Qt Designer, the GUI designer for Qt widgets-based applications
You can use Qt Creator to develop with other Qt versions as well:
http://qt-project.org/doc/qtcreator-2.6/creator-project-qmake.html
Running Example Applications
----------------------------
You can open example applications in the Qt Creator Welcome mode to build and
run them.
The QML based Quick 2 examples are located in
<install_dir>/<version>/<compiler>/examples/qtdeclarative. You can load them
using the qmlscene application.
The QML based Quick 1 examples are located in
<install_dir>/<version>/<compiler>/examples/qtquick1. You can view them with the
QMLViewer application.
You can open most example applications in the Qt Creator Welcome mode to build
and run them. Additional examples can be opened by browsing
<install_dir>/<version>/<compiler>/examples.
Building Qt 5 from Source
-------------------------

View File

@ -46,6 +46,7 @@
Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen)
: m_initialized(false)
, m_format(format)
, m_currentWindow(0)
{
m_context = new QOpenGLContext(this);
if (screen)
@ -57,7 +58,7 @@ Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *scree
}
HelloWindow::HelloWindow(const QSharedPointer<Renderer> &renderer)
: m_colorIndex(0), m_renderer(renderer), m_timer(0)
: m_colorIndex(0), m_renderer(renderer)
{
setSurfaceType(QWindow::OpenGLSurface);
setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
@ -68,21 +69,12 @@ HelloWindow::HelloWindow(const QSharedPointer<Renderer> &renderer)
create();
connect(this, SIGNAL(needRender(QSurface *, const QColor &, const QSize &)),
renderer.data(), SLOT(render(QSurface *, const QColor &, const QSize &)));
updateColor();
}
void HelloWindow::exposeEvent(QExposeEvent *)
{
render();
if (!m_timer) {
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(render()));
m_timer->start(10);
}
m_renderer->setAnimating(this, isExposed());
}
void HelloWindow::mousePressEvent(QMouseEvent *)
@ -90,14 +82,16 @@ void HelloWindow::mousePressEvent(QMouseEvent *)
updateColor();
}
void HelloWindow::render()
QColor HelloWindow::color() const
{
if (isExposed())
emit needRender(this, m_color, size());
QMutexLocker locker(&m_colorLock);
return m_color;
}
void HelloWindow::updateColor()
{
QMutexLocker locker(&m_colorLock);
QColor colors[] =
{
QColor(100, 255, 0),
@ -108,11 +102,41 @@ void HelloWindow::updateColor()
m_colorIndex = 1 - m_colorIndex;
}
void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewSize)
void Renderer::setAnimating(HelloWindow *window, bool animating)
{
QMutexLocker locker(&m_windowLock);
if (m_windows.contains(window) == animating)
return;
if (animating) {
m_windows << window;
if (m_windows.size() == 1)
QTimer::singleShot(0, this, SLOT(render()));
} else {
m_currentWindow = 0;
m_windows.removeOne(window);
}
}
void Renderer::render()
{
QMutexLocker locker(&m_windowLock);
if (m_windows.isEmpty())
return;
HelloWindow *surface = m_windows.at(m_currentWindow);
QColor color = surface->color();
m_currentWindow = (m_currentWindow + 1) % m_windows.size();
if (!m_context->makeCurrent(surface))
return;
QSize viewSize = surface->size();
locker.unlock();
if (!m_initialized) {
initialize();
m_initialized = true;
@ -146,6 +170,8 @@ void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewS
m_context->swapBuffers(surface);
m_fAngle += 1.0f;
QTimer::singleShot(0, this, SLOT(render()));
}
void Renderer::paintQtLogo()

View File

@ -41,10 +41,13 @@
#include <QWindow>
#include <QColor>
#include <QMutex>
#include <QOpenGLShaderProgram>
#include <QSharedPointer>
#include <QTimer>
class HelloWindow;
class Renderer : public QObject
{
Q_OBJECT
@ -54,8 +57,10 @@ public:
QSurfaceFormat format() const { return m_format; }
public slots:
void render(QSurface *surface, const QColor &color, const QSize &viewSize);
void setAnimating(HelloWindow *window, bool animating);
private slots:
void render();
private:
void initialize();
@ -78,30 +83,28 @@ private:
QSurfaceFormat m_format;
QOpenGLContext *m_context;
QOpenGLShaderProgram *m_program;
QList<HelloWindow *> m_windows;
int m_currentWindow;
QMutex m_windowLock;
};
class HelloWindow : public QWindow
{
Q_OBJECT
public:
explicit HelloWindow(const QSharedPointer<Renderer> &renderer);
QColor color() const;
void updateColor();
void exposeEvent(QExposeEvent *event);
signals:
void needRender(QSurface *surface, const QColor &color, const QSize &viewSize);
private slots:
void render();
private:
void mousePressEvent(QMouseEvent *);
int m_colorIndex;
QColor m_color;
const QSharedPointer<Renderer> m_renderer;
QTimer *m_timer;
mutable QMutex m_colorLock;
};

View File

@ -34,6 +34,8 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON = -qrtti
QMAKE_CXXFLAGS_RTTI_OFF = -qnortti
QMAKE_COMPILER_DEFINES += __xlC__
QMAKE_INCDIR =

View File

@ -179,6 +179,6 @@ QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
load(qt_config)

View File

@ -40,3 +40,26 @@ defineReplace(cmakeTargetPaths) {
}
return ($$join(out, " "))
}
defineReplace(cmakePortablePaths) {
variable = $$1
out =
for(v, variable) {
out += ${CMAKE_FIND_ROOT_PATH}$$cmakeTargetPath($$v)
}
return ($$join(out, ";"))
}
defineReplace(cmakeProcessLibs) {
variable = $$1
out =
for(v, variable) {
if(!equals(v, -framework)) {
v ~= s,^-l,,
v ~= s,^-lib,,
v ~= s,.lib$,,
out += $$v
}
}
return ($$join(out, ";"))
}

View File

@ -57,6 +57,8 @@ isEmpty(CMAKE_VERSION) {
dependentmodules -= $$CMAKE_QT_MODULES_UNDER_TEST
dependentmodules = $$cmakeModuleList($$dependentmodules)
contains(QT_CONFIG, angle): CMAKE_ANGLE_DEFINE = -DQT_WITH_ANGLE=True
CMAKE_MODULE_VERSIONS =
CMAKE_MODULES_UNDER_TEST =
for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) {
@ -74,6 +76,7 @@ isEmpty(CMAKE_VERSION) {
cmake $$_PRO_FILE_PWD_ $$CMAKE_GENERATOR \
-DCMAKE_VERBOSE_MAKEFILE=1 \
$$CMAKE_MODULE_DEFINES \
$$CMAKE_ANGLE_DEFINE \
-DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \
-DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \
-DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" \

View File

@ -0,0 +1,34 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
TEMPLATE = app
load(qt_build_paths)
DESTDIR = $$MODULE_BASE_OUTDIR/bin
isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle
host_build: QT -= gui # no host tool will ever use gui
host_build:force_bootstrap {
!build_pass: CONFIG += release
contains(QT, core(-private)?|xml) {
QT -= core core-private xml
QT += bootstrap-private
}
target.path = $$[QT_HOST_BINS]
} else {
!build_pass:contains(QT_CONFIG, build_all): CONFIG += release
target.path = $$[QT_INSTALL_BINS]
}
INSTALLS += target
load(qt_targets)
load(qt_common)

View File

@ -50,3 +50,19 @@ CONFIG += \
# Qt modules get compiled without exceptions enabled by default.
# However, testcases should be still built with exceptions.
exceptions_off testcase_exceptions
defineTest(qtBuildPart) {
bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS)
isEmpty(bp): bp = $$QT_BUILD_PARTS
contains(bp, $$1): return(true)
return(false)
}
defineTest(qtNomakeTools) {
qtBuildPart(tools): return()
for (d, 1) {
$${d}.CONFIG += no_default_target no_default_install
export($${d}.CONFIG)
}
}

View File

@ -19,22 +19,24 @@ TEMPLATE = subdirs
bp = $$eval($$upper($$TARGET)_BUILD_PARTS)
!isEmpty(bp): QT_BUILD_PARTS = $$bp
sub_src.subdir = src
sub_src.target = sub-src
SUBDIRS = sub_src
exists($$_PRO_FILE_PWD_/src/src.pro) {
sub_src.subdir = src
sub_src.target = sub-src
SUBDIRS += sub_src
exists($$_PRO_FILE_PWD_/tools/tools.pro) {
sub_tools.subdir = tools
sub_tools.target = sub-tools
sub_tools.depends = sub_src
!contains(QT_BUILD_PARTS, tools): sub_tools.CONFIG = no_default_target no_default_install
SUBDIRS += sub_tools
exists($$_PRO_FILE_PWD_/tools/tools.pro) {
sub_tools.subdir = tools
sub_tools.target = sub-tools
sub_tools.depends = sub_src
# conditional treatment happens on a case-by-case basis
SUBDIRS += sub_tools
}
}
exists($$_PRO_FILE_PWD_/examples/examples.pro) {
sub_examples.subdir = examples
sub_examples.target = sub-examples
sub_examples.depends = sub_src
contains(SUBDIRS, sub_src): sub_examples.depends = sub_src
examples_need_tools: sub_examples.depends += sub_tools
!contains(QT_BUILD_PARTS, examples): sub_examples.CONFIG = no_default_target no_default_install
SUBDIRS += sub_examples
@ -44,7 +46,7 @@ exists($$_PRO_FILE_PWD_/examples/examples.pro) {
exists($$_PRO_FILE_PWD_/demos/demos.pro) {
sub_demos.subdir = demos
sub_demos.target = sub-demos
sub_demos.depends = sub_src
contains(SUBDIRS, sub_src): sub_demos.depends = sub_src
examples_need_tools: sub_demos.depends += sub_tools
!contains(QT_BUILD_PARTS, examples): sub_demos.CONFIG = no_default_target no_default_install
SUBDIRS += sub_demos
@ -53,7 +55,7 @@ exists($$_PRO_FILE_PWD_/demos/demos.pro) {
exists($$_PRO_FILE_PWD_/tests/tests.pro) {
sub_tests.subdir = tests
sub_tests.target = sub-tests
sub_tests.depends = sub_src # The tests may have a run-time only dependency on other parts
contains(SUBDIRS, sub_src): sub_tests.depends = sub_src # The tests may have a run-time only dependency on other parts
tests_need_tools: sub_tests.depends += sub_tools
sub_tests.CONFIG = no_default_install
!contains(QT_BUILD_PARTS, tests) {

View File

@ -9,30 +9,9 @@
# We mean it.
#
TEMPLATE = app
load(qt_build_paths)
DESTDIR = $$MODULE_BASE_OUTDIR/bin
load(qt_app)
CONFIG += console
isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle
host_build: QT -= gui # no host tool will ever use gui
host_build:force_bootstrap {
!build_pass: CONFIG += release
contains(QT, core(-private)?|xml) {
QT -= core core-private xml
QT += bootstrap-private
}
target.path = $$[QT_HOST_BINS]
} else {
!build_pass:contains(QT_CONFIG, build_all): CONFIG += release
target.path = $$[QT_INSTALL_BINS]
}
INSTALLS += target
load(qt_targets)
load(qt_common)
# If we are doing a prefix build, create a "module" pri which enables
# qtPrepareTool() to work with the non-installed build.

View File

@ -338,6 +338,7 @@ Option::init(int argc, char **argv)
QDir currentDir = QDir::current();
#ifdef Q_OS_WIN
QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
paths.prepend(QLatin1String("."));
#else
QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
#endif

View File

@ -180,3 +180,5 @@ EXPORTS
glGetCurrentContext @147 NONAME
glGetProcAddress@4 @148 NONAME
glBindTexImage@4 @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME

View File

@ -180,3 +180,5 @@ EXPORTS
glGetCurrentContext @147 NONAME
glGetProcAddress@4 @148 NONAME
glBindTexImage@4 @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME

View File

@ -9,6 +9,8 @@
#ifndef LIBGLESV2_MATHUTIL_H_
#define LIBGLESV2_MATHUTIL_H_
#include <intrin.h>
#include "common/system.h"
#include "common/debug.h"

View File

@ -0,0 +1,30 @@
From 142312b5cbea10257b6d3693b48817ae657018eb Mon Sep 17 00:00:00 2001
From: Kai Koehne <kai.koehne@digia.com>
Date: Mon, 22 Apr 2013 16:36:17 +0200
Subject: [PATCH] Add missing intrin.h include for __cpuid
This is already fixed upstream in
https://codereview.appspot.com/8615046/patch/1/2
Change-Id: I4b9e865f6b5622c484418a8381334381bc256887
---
src/3rdparty/angle/src/libGLESv2/mathutil.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h
index 672c443..bb48b94 100644
--- a/src/3rdparty/angle/src/libGLESv2/mathutil.h
+++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h
@@ -9,6 +9,8 @@
#ifndef LIBGLESV2_MATHUTIL_H_
#define LIBGLESV2_MATHUTIL_H_
+#include <intrin.h>
+
#include "common/system.h"
#include "common/debug.h"
--
1.8.1.msysgit.1

View File

@ -87,7 +87,7 @@ SOURCES += \
$$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/VertexDataManager.cpp
sse2:SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/ImageSSE2.cpp
SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/ImageSSE2.cpp
angle_d3d11 {
HEADERS += \

View File

@ -38,6 +38,10 @@ foreach(module ${CMAKE_MODULES_UNDER_TEST})
)
endforeach()
if(CMAKE_CROSSCOMPILING AND CMAKE_FIND_ROOT_PATH)
list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_CXX_LINK_FLAGS=--sysroot=\"${CMAKE_FIND_ROOT_PATH}\"")
endif()
macro(expect_pass _dir)
string(REPLACE "(" "_" testname "${_dir}")
string(REPLACE ")" "_" testname "${testname}")

View File

@ -79,7 +79,7 @@ class QFlags
{
Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)),
"QFlags uses an int as storage, so an enum with underlying "
"long long would overflow. Qt 5.1 will have support for 64bit enums.");
"long long will overflow.");
struct Private;
typedef int (Private::*Zero);
public:

View File

@ -138,6 +138,10 @@ public:
Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)
//shorter names for shortcuts
// The use of all-caps identifiers has the potential for clashing with
// user-defined or third-party macros. More so when the identifiers are not
// "namespace"-prefixed. This is considered bad practice and is why
// KeypadModifier was not added to the Modifier enum.
enum Modifier {
META = Qt::MetaModifier,
SHIFT = Qt::ShiftModifier,

View File

@ -817,8 +817,12 @@ QDataStream &QDataStream::operator>>(double &f)
Reads the '\\0'-terminated string \a s from the stream and returns
a reference to the stream.
Space for the string is allocated using \c new -- the caller must
destroy it with \c{delete[]}.
The string is deserialized using \c{readBytes()}.
Space for the string is allocated using \c{new []} -- the caller must
destroy it with \c{delete []}.
\sa readBytes(), readRawData()
*/
QDataStream &QDataStream::operator>>(char *&s)
@ -832,8 +836,8 @@ QDataStream &QDataStream::operator>>(char *&s)
Reads the buffer \a s from the stream and returns a reference to
the stream.
The buffer \a s is allocated using \c new. Destroy it with the \c
delete[] operator.
The buffer \a s is allocated using \c{new []}. Destroy it with the
\c{delete []} operator.
The \a l parameter is set to the length of the buffer. If the
string read is empty, \a l is set to 0 and \a s is set to
@ -1102,7 +1106,9 @@ QDataStream &QDataStream::operator<<(double f)
Writes the '\\0'-terminated string \a s to the stream and returns a
reference to the stream.
The string is serialized using writeBytes().
The string is serialized using \c{writeBytes()}.
\sa writeBytes(), writeRawData()
*/
QDataStream &QDataStream::operator<<(const char *s)

View File

@ -187,6 +187,8 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons
QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const
{
Q_ASSERT(fileEngine); // should never be called when using the native FS
if (fileTimes.size() != 3)
fileTimes.resize(3);
if (!cache_enabled)
clearFlags();
uint cf;

View File

@ -58,6 +58,7 @@
#include "qatomic.h"
#include "qshareddata.h"
#include "qfilesystemengine_p.h"
#include "qvector.h"
#include <QtCore/private/qabstractfileengine_p.h>
#include <QtCore/private/qfilesystementry_p.h>
@ -152,7 +153,12 @@ public:
bool cache_enabled : 1;
mutable uint fileFlags;
mutable qint64 fileSize;
mutable QDateTime fileTimes[3];
// ### Qt6: FIXME: This vector is essentially a plain array
// mutable QDateTime fileTimes[3], but the array is slower
// to initialize than the QVector as QDateTime has a pimpl.
// In Qt 6, QDateTime should inline its data members,
// and this here can be an array again.
mutable QVector<QDateTime> fileTimes;
inline bool getCachedFlag(uint c) const
{ return cache_enabled ? (cachedFlags & c) : 0; }
inline void setCachedFlag(uint c) const

View File

@ -125,16 +125,15 @@ QT_BEGIN_NAMESPACE
The environment of the calling process can be obtained using
QProcessEnvironment::systemEnvironment().
On Unix systems, the variable names are case-sensitive. For that reason,
this class will not touch the names of the variables. Note as well that
On Unix systems, the variable names are case-sensitive. Note that the
Unix environment allows both variable names and contents to contain arbitrary
binary data (except for the NUL character), but this is not supported by
QProcessEnvironment. This class only supports names and values that are
encodable by the current locale settings (see QTextCodec::codecForLocale).
binary data (except for the NUL character). QProcessEnvironment will preserve
such variables, but does not support manipulating variables whose names or
values are not encodable by the current locale settings (see
QTextCodec::codecForLocale).
On Windows, the variable names are case-insensitive. Therefore,
QProcessEnvironment will always uppercase the names and do case-insensitive
comparisons.
On Windows, the variable names are case-insensitive, but case-preserving.
QProcessEnvironment behaves accordingly.
On Windows CE, the concept of environment does not exist. This class will
keep the values set for compatibility with other platforms, but the values
@ -298,9 +297,6 @@ void QProcessEnvironment::clear()
Returns true if the environment variable of name \a name is found in
this QProcessEnvironment object.
On Windows, variable names are case-insensitive, so the key is converted
to uppercase before searching. On other systems, names are case-sensitive
so no trasformation is applied.
\sa insert(), value()
*/
@ -314,10 +310,6 @@ bool QProcessEnvironment::contains(const QString &name) const
into this QProcessEnvironment object. If that variable already existed,
it is replaced by the new value.
On Windows, variable names are case-insensitive, so this function always
uppercases the variable name before inserting. On other systems, names
are case-sensitive, so no transformation is applied.
On most systems, inserting a variable with no contents will have the
same effect for applications as if the variable had not been set at all.
However, to guarantee that there are no incompatibilities, to remove a
@ -336,9 +328,6 @@ void QProcessEnvironment::insert(const QString &name, const QString &value)
QProcessEnvironment object. If that variable did not exist before,
nothing happens.
On Windows, variable names are case-insensitive, so the key is converted
to uppercase before searching. On other systems, names are case-sensitive
so no trasformation is applied.
\sa contains(), insert(), value()
*/
@ -353,10 +342,6 @@ void QProcessEnvironment::remove(const QString &name)
\a name and returns its value. If the variable is not found in this object,
then \a defaultValue is returned instead.
On Windows, variable names are case-insensitive, so the key is converted
to uppercase before searching. On other systems, names are case-sensitive
so no trasformation is applied.
\sa contains(), insert(), remove()
*/
QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const
@ -376,10 +361,10 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa
each environment variable that is set. The environment variable's name
and its value are separated by an equal character ('=').
The QStringList contents returned by this function are suitable for use
with the QProcess::setEnvironment function. However, it is recommended
to use QProcess::setProcessEnvironment instead since that will avoid
unnecessary copying of the data.
The QStringList contents returned by this function are suitable for
presentation.
Use with the QProcess::setEnvironment function is not recommended due to
potential encoding problems under Unix, and worse performance.
\sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(),
QProcess::setEnvironment()

View File

@ -410,7 +410,7 @@ inline bool QAbstractItemModel::moveRow(const QModelIndex &sourceParent, int sou
{ return moveRows(sourceParent, sourceRow, 1, destinationParent, destinationChild); }
inline bool QAbstractItemModel::moveColumn(const QModelIndex &sourceParent, int sourceColumn,
const QModelIndex &destinationParent, int destinationChild)
{ return moveRows(sourceParent, sourceColumn, 1, destinationParent, destinationChild); }
{ return moveColumns(sourceParent, sourceColumn, 1, destinationParent, destinationChild); }
inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, void *adata) const
{ return QModelIndex(arow, acolumn, adata, this); }
inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, quintptr aid) const

View File

@ -53,10 +53,10 @@
// We mean it.
//
QT_BEGIN_NAMESPACE
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
/*
Locks 2 mutexes in a defined order, avoiding a recursive lock if
we're trying to lock the same mutex twice.

View File

@ -124,8 +124,8 @@
Releases the \a lockedMutex and waits on the wait condition. The
\a lockedMutex must be initially locked by the calling thread. If \a
lockedMutex is not in a locked state, this function returns
immediately. If \a lockedMutex is a recursive mutex, this function
lockedMutex is not in a locked state, the behavior is undefined. If
\a lockedMutex is a recursive mutex, this function
returns immediately. The \a lockedMutex will be unlocked, and the
calling thread will block until either of these conditions is met:

View File

@ -262,6 +262,10 @@ public:
private:
friend class QDateTimePrivate;
void detach();
// ### Qt6: Using a private here has high impact on runtime
// on users such as QFileInfo. In Qt 6, the data members
// should be inlined.
QExplicitlySharedDataPointer<QDateTimePrivate> d;
#ifndef QT_NO_DATASTREAM

View File

@ -284,51 +284,51 @@ QLocaleId QLocaleId::withLikelySubtagsRemoved() const
return max;
}
QString QLocaleId::bcp47Name() const
QByteArray QLocaleId::name(char separator) const
{
if (language_id == QLocale::AnyLanguage)
return QString();
return QByteArray();
if (language_id == QLocale::C)
return QStringLiteral("C");
return QByteArrayLiteral("C");
const unsigned char *lang = language_code_list + 3*uint(language_id);
const unsigned char *lang = language_code_list + 3 * language_id;
const unsigned char *script =
(script_id != QLocale::AnyScript ? script_code_list + 4*uint(script_id) : 0);
(script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : 0);
const unsigned char *country =
(country_id != QLocale::AnyCountry ? country_code_list + 3*uint(country_id) : 0);
(country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : 0);
char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0);
QString name(len, Qt::Uninitialized);
QChar *uc = name.data();
*uc++ = ushort(lang[0]);
*uc++ = ushort(lang[1]);
QByteArray name(len, Qt::Uninitialized);
char *uc = name.data();
*uc++ = lang[0];
*uc++ = lang[1];
if (lang[2] != 0)
*uc++ = ushort(lang[2]);
*uc++ = lang[2];
if (script) {
*uc++ = QLatin1Char('-');
*uc++ = ushort(script[0]);
*uc++ = ushort(script[1]);
*uc++ = ushort(script[2]);
*uc++ = ushort(script[3]);
*uc++ = separator;
*uc++ = script[0];
*uc++ = script[1];
*uc++ = script[2];
*uc++ = script[3];
}
if (country) {
*uc++ = QLatin1Char('-');
*uc++ = ushort(country[0]);
*uc++ = ushort(country[1]);
*uc++ = separator;
*uc++ = country[0];
*uc++ = country[1];
if (country[2] != 0)
*uc++ = ushort(country[2]);
*uc++ = country[2];
}
return name;
}
QString QLocalePrivate::bcp47Name() const
QByteArray QLocalePrivate::bcp47Name(char separator) const
{
if (m_data->m_language_id == QLocale::AnyLanguage)
return QString();
return QByteArray();
if (m_data->m_language_id == QLocale::C)
return QStringLiteral("C");
return QByteArrayLiteral("C");
QLocaleId localeId = QLocaleId::fromIds(m_data->m_language_id, m_data->m_script_id, m_data->m_country_id);
return localeId.withLikelySubtagsRemoved().bcp47Name();
return localeId.withLikelySubtagsRemoved().name(separator);
}
const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
@ -1080,7 +1080,7 @@ QString QLocale::name() const
*/
QString QLocale::bcp47Name() const
{
return d->bcp47Name();
return QString::fromLatin1(d->bcp47Name());
}
/*!
@ -2494,7 +2494,7 @@ QString QLocale::toUpper(const QString &str) const
{
#ifdef QT_USE_ICU
bool ok = true;
QString result = QIcu::toUpper(d->m_localeID, str, &ok);
QString result = QIcu::toUpper(d->bcp47Name('_'), str, &ok);
if (ok)
return result;
// else fall through and use Qt's toUpper
@ -2511,7 +2511,7 @@ QString QLocale::toLower(const QString &str) const
{
#ifdef QT_USE_ICU
bool ok = true;
QString result = QIcu::toLower(d->m_localeID, str, &ok);
const QString result = QIcu::toLower(d->bcp47Name('_'), str, &ok);
if (ok)
return result;
// else fall through and use Qt's toUpper
@ -3662,14 +3662,14 @@ QStringList QLocale::uiLanguages() const
const QLocaleId min = max.withLikelySubtagsRemoved();
QStringList uiLanguages;
uiLanguages.append(min.bcp47Name());
uiLanguages.append(QString::fromLatin1(min.name()));
if (id.script_id) {
id.script_id = 0;
if (id != min && id.withLikelySubtagsAdded() == max)
uiLanguages.append(id.bcp47Name());
uiLanguages.append(QString::fromLatin1(id.name()));
}
if (max != min && max != id)
uiLanguages.append(max.bcp47Name());
uiLanguages.append(QString::fromLatin1(max.name()));
return uiLanguages;
}

View File

@ -151,7 +151,7 @@ struct QLocaleId
QLocaleId withLikelySubtagsAdded() const;
QLocaleId withLikelySubtagsRemoved() const;
QString bcp47Name() const;
QByteArray name(char separator = '-') const;
ushort language_id, script_id, country_id;
};
@ -212,8 +212,6 @@ public:
: m_index(index), m_numberOptions(numberOptions)
{
m_data = dataPointerForIndex(index);
m_localeID = bcp47Name().toLatin1();
m_localeID.replace('-','_');
}
~QLocalePrivate()
@ -232,7 +230,7 @@ public:
quint16 languageId() const { return m_data->m_language_id; }
quint16 countryId() const { return m_data->m_country_id; }
QString bcp47Name() const;
QByteArray bcp47Name(char separator = '-') const;
// ### QByteArray::fromRawData would be more optimal
inline QString languageCode() const { return QLocalePrivate::languageToCode(QLocale::Language(m_data->m_language_id)); }
@ -334,11 +332,9 @@ public:
QString dateTimeToString(const QString &format, const QDate *date, const QTime *time,
const QLocale *q) const;
friend class QLocale;
quint16 m_index;
quint16 m_numberOptions;
const QLocaleData *m_data;
QByteArray m_localeID;
};
inline char QLocalePrivate::digitToCLocale(QChar in) const

View File

@ -1,7 +1,7 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
# Name of the project which must match the outputdir. Determines the .index file
project = qtdbus
project = QtDBus
# Directories in which to search for files to document and images.
# By default set to the root directory of the project for sources
@ -29,23 +29,23 @@ depends += qtcore
# Defines the name of the project. You cannot use operators (+, =, -) in
# the name. Properties for this project are set using a qhp.<projectname>.property
# format.
qhp.projects = qtdbus
qhp.projects = QtDBus
# Sets the name of the output qhp file.
qhp.qtdbus.file = qtdbus.qhp
qhp.QtDBus.file = qtdbus.qhp
# Namespace for the output file. This namespace is used to distinguish between
# different documentation files in Creator/Assistant.
qhp.qtdbus.namespace = org.qt-project.qtdbus.$QT_VERSION_TAG
qhp.QtDBus.namespace = org.qt-project.qtdbus.$QT_VERSION_TAG
# Title for the package, will be the main title for the package in
# Assistant/Creator.
qhp.qtdbus.indexTitle = Qt D-Bus
qhp.QtDBus.indexTitle = Qt D-Bus
# Only update the name of the project for the next variables.
qhp.qtdbus.virtualFolder = qtdbus
qhp.qtdbus.subprojects = classes
qhp.qtdbus.subprojects.classes.title = C++ Classes
qhp.qtdbus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes
qhp.qtdbus.subprojects.classes.selectors = class fake:headerfile
qhp.qtdbus.subprojects.classes.sortPages = true
qhp.QtDBus.virtualFolder = qtdbus
qhp.QtDBus.subprojects = classes
qhp.QtDBus.subprojects.classes.title = C++ Classes
qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes
qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile
qhp.QtDBus.subprojects.classes.sortPages = true

View File

@ -1,5 +1,48 @@
!!IF !contains(QT_CONFIG, angle)
!!IF !isEmpty(CMAKE_ANGLE_EGL_DLL_RELEASE)
!!IF isEmpty(CMAKE_INCLUDE_DIR_IS_ABSOLUTE)
set(Qt5Gui_EGL_INCLUDE_DIRS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$$CMAKE_INCLUDE_DIR\")
!!ELSE
set(Qt5Gui_EGL_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\")
!!ENDIF
set(Qt5Gui_OPENGL_INCLUDE_DIRS ${Qt5Gui_EGL_INCLUDE_DIRS})
macro(_populate_qt5gui_gl_target_properties TargetName Configuration LIB_LOCATION IMPLIB_LOCATION)
set_property(TARGET Qt5::${TargetName} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
set_target_properties(Qt5::${TargetName} PROPERTIES
!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE)
\"IMPORTED_LOCATION_${Configuration}\" \"${_qt5Gui_install_prefix}/$${CMAKE_LIB_DIR}${LIB_LOCATION}\"
!!ELSE
\"IMPORTED_LOCATION_${Configuration}\" \"$${CMAKE_LIB_DIR}${LIB_LOCATION}\"
!!ENDIF
!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE)
\"IMPORTED_IMPLIB_${Configuration}\" \"${_qt5Gui_install_prefix}/$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\"
!!ELSE
\"IMPORTED_IMPLIB_${Configuration}\" \"$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\"
!!ENDIF
)
endmacro()
add_library(Qt5::Gui_EGL SHARED IMPORTED)
_populate_qt5gui_gl_target_properties(Gui_EGL RELEASE $${CMAKE_ANGLE_EGL_DLL_RELEASE} $${CMAKE_ANGLE_EGL_IMPLIB_RELEASE})
add_library(Qt5::Gui_GLESv2 SHARED IMPORTED)
_populate_qt5gui_gl_target_properties(Gui_GLESv2 RELEASE $${CMAKE_ANGLE_GLES2_DLL_RELEASE} $${CMAKE_ANGLE_GLES2_IMPLIB_RELEASE})
set_property(TARGET Qt5::Gui_EGL APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_EGL_INCLUDE_DIRS})
set_property(TARGET Qt5::Gui_GLESv2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_OPENGL_INCLUDE_DIRS})
!!IF !isEmpty(CMAKE_DEBUG_TYPE)
_populate_qt5gui_gl_target_properties(Gui_EGL DEBUG $${CMAKE_ANGLE_EGL_DLL_DEBUG} $${CMAKE_ANGLE_EGL_IMPLIB_DEBUG})
_populate_qt5gui_gl_target_properties(Gui_GLESv2 DEBUG $${CMAKE_ANGLE_GLES2_DLL_DEBUG} $${CMAKE_ANGLE_GLES2_IMPLIB_DEBUG})
!!ENDIF
set(Qt5Gui_EGL_LIBRARIES Qt5::Gui_EGL)
set(Qt5Gui_OPENGL_LIBRARIES Qt5::Gui_GLESv2)
!!ELSE
!!IF !isEmpty(CMAKE_GL_INCDIRS)
@ -17,4 +60,67 @@ unset(_qt5gui_OPENGL_INCLUDE_DIR CACHE)
!!ENDIF
macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs)
set(Qt5Gui_${Name}_LIBRARIES)
set(Qt5Gui_EGL_INCLUDE_DIRS ${IncDirs})
foreach(_lib ${Libs})
string(REGEX REPLACE "[^_A-Za-z0-9]" "_" _cmake_lib_name ${_lib})
if (NOT TARGET Qt5::Gui_${_cmake_lib_name})
find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib}
!!IF !isEmpty(CROSS_COMPILE)
PATHS \"${LibDir}\" NO_DEFAULT_PATH
!!ENDIF
)
!!IF mac
set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}")
!!ENDIF
if (NOT Qt5Gui_${_cmake_lib_name}_LIBRARY)
message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\", using the CMAKE_FIND_ROOT_PATH \\\"${CMAKE_FIND_ROOT_PATH}\\\".\")
endif()
add_library(Qt5::Gui_${_cmake_lib_name} SHARED IMPORTED)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${IncDirs})
set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\")
!!IF !isEmpty(CMAKE_WINDOWS_BUILD)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\")
!!ENDIF
unset(Qt5Gui_${_cmake_lib_name}_LIBRARY CACHE)
find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG ${_lib}d
PATHS \"${LibDir}\" NO_DEFAULT_PATH)
if (Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\")
!!IF !isEmpty(CMAKE_WINDOWS_BUILD)
set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\")
!!ENDIF
endif()
unset(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG CACHE)
endif()
list(APPEND Qt5Gui_${Name}_LIBRARIES Qt5::Gui_${_cmake_lib_name})
endforeach()
endmacro()
!!IF !isEmpty(CMAKE_EGL_LIBS)
_qt5gui_find_extra_libs(EGL \"$$CMAKE_EGL_LIBS\" \"$$CMAKE_EGL_LIBDIR\" \"$$CMAKE_EGL_INCDIRS\")
!!ENDIF
!!IF !isEmpty(CMAKE_OPENGL_LIBS)
_qt5gui_find_extra_libs(OPENGL \"$$CMAKE_OPENGL_LIBS\" \"$$CMAKE_OPENGL_LIBDIR\" \"$$CMAKE_OPENGL_INCDIRS\")
!!ENDIF
!!ENDIF
set(Qt5Gui_OPENGL_IMPLEMENTATION $$CMAKE_QT_OPENGL_IMPLEMENTATION)
get_target_property(_configs Qt5::Gui IMPORTED_CONFIGURATIONS)
foreach(_config ${_configs})
set_property(TARGET Qt5::Gui APPEND PROPERTY
IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config}
${Qt5Gui_EGL_LIBRARIES} ${Qt5Gui_OPENGL_LIBRARIES}
)
endforeach()
unset(_configs)

View File

@ -66,11 +66,8 @@ class QTextCursor;
// We need to inherit QObject to expose the enums to QML.
class Q_GUI_EXPORT QAccessible
#ifndef Q_QDOC
:public QObject
#endif
{
Q_OBJECT
Q_GADGET
Q_ENUMS(Role Event State)
public:

View File

@ -37,18 +37,49 @@ QMAKE_LIBS += $$QMAKE_LIBS_GUI
load(cmake_functions)
!contains(QT_CONFIG, angle) {
win32: CMAKE_WINDOWS_BUILD = True
contains(QT_CONFIG, angle) {
CMAKE_GL_INCDIRS = $$CMAKE_INCLUDE_DIR
CMAKE_ANGLE_EGL_DLL_RELEASE = libEGL.dll
CMAKE_ANGLE_EGL_IMPLIB_RELEASE = libEGL.lib
CMAKE_ANGLE_GLES2_DLL_RELEASE = libGLESv2.dll
CMAKE_ANGLE_GLES2_IMPLIB_RELEASE = libGLESv2.lib
CMAKE_ANGLE_EGL_DLL_DEBUG = libEGLd.dll
CMAKE_ANGLE_EGL_IMPLIB_DEBUG = libEGLd.lib
CMAKE_ANGLE_GLES2_DLL_DEBUG = libGLESv2d.dll
CMAKE_ANGLE_GLES2_IMPLIB_DEBUG = libGLESv2d.lib
CMAKE_QT_OPENGL_IMPLEMENTATION = GLESv2
} else {
CMAKE_EGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_EGL)
!isEmpty(QMAKE_LIBDIR_EGL): CMAKE_EGL_LIBDIR += $$cmakeTargetPath($$QMAKE_LIBDIR_EGL)
contains(QT_CONFIG, opengles1) {
CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1)
!isEmpty(QMAKE_INCDIR_OPENGL_ES1): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1)
CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES1)
CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES1)
!isEmpty(QMAKE_LIBDIR_OPENGL_ES1): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES1)
CMAKE_GL_HEADER_NAME = GLES/gl.h
CMAKE_QT_OPENGL_IMPLEMENTATION = GLES
} else:contains(QT_CONFIG, opengles2) {
CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2)
!isEmpty(QMAKE_INCDIR_OPENGL_ES2): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2)
CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES2)
CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES2)
!isEmpty(QMAKE_LIBDIR_OPENGL_ES2): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES2)
CMAKE_GL_HEADER_NAME = GLES2/gl2.h
CMAKE_QT_OPENGL_IMPLEMENTATION = GLESv2
} else {
CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL)
!isEmpty(QMAKE_INCDIR_OPENGL): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL)
CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL)
CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL)
!isEmpty(QMAKE_LIBDIR_OPENGL): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL)
CMAKE_GL_HEADER_NAME = GL/gl.h
mac: CMAKE_GL_HEADER_NAME = gl.h
CMAKE_QT_OPENGL_IMPLEMENTATION = GL
}
}
CMAKE_EGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_EGL)
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist

View File

@ -483,6 +483,11 @@ void QPixmapIconEngine::virtual_hook(int id, void *data)
#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
QFactoryLoader *qt_iconEngineFactoryLoader()
{
return loader();
}
#endif

View File

@ -104,6 +104,10 @@ static inline QStringList systemIconSearchPaths()
return QStringList();
}
#ifndef QT_NO_LIBRARY
extern QFactoryLoader *qt_iconEngineFactoryLoader(); // qicon.cpp
#endif
void QIconLoader::ensureInitialized()
{
if (!m_initialized) {
@ -116,10 +120,7 @@ void QIconLoader::ensureInitialized()
if (m_systemTheme.isEmpty())
m_systemTheme = fallbackTheme();
#ifndef QT_NO_LIBRARY
QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterface_iid,
QLatin1String("/iconengines"),
Qt::CaseInsensitive);
if (iconFactoryLoader.keyMap().key(QLatin1String("svg"), -1) != -1)
if (qt_iconEngineFactoryLoader()->keyMap().key(QLatin1String("svg"), -1) != -1)
m_supportsSvg = true;
#endif //QT_NO_LIBRARY
}

View File

@ -966,7 +966,7 @@ QKeyEvent::~QKeyEvent()
\sa QApplication::keyboardModifiers()
*/
//###### We must check with XGetModifierMapping
Qt::KeyboardModifiers QKeyEvent::modifiers() const
{
if (key() == Qt::Key_Shift)
@ -977,6 +977,8 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::AltModifier);
if (key() == Qt::Key_Meta)
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::MetaModifier);
if (key() == Qt::Key_AltGr)
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::GroupSwitchModifier);
return QInputEvent::modifiers();
}
@ -990,10 +992,10 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const
*/
bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const
{
uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier); //The keypad modifier should not make a difference
//The keypad and group switch modifier should not make a difference
uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier | Qt::GroupSwitchModifier);
const uint platform = QKeySequencePrivate::currentKeyPlatforms();
uint N = QKeySequencePrivate::numberOfKeyBindings;
int first = 0;
int last = N - 1;

View File

@ -1640,6 +1640,10 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
}
emit qApp->focusWindowChanged(newFocus);
if (previous)
emit previous->activeChanged();
if (newFocus)
emit newFocus->activeChanged();
}
void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
@ -1736,6 +1740,9 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
QCloseEvent event;
QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
if (e->accepted) {
*(e->accepted) = !event.isAccepted();
}
}
void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e)

View File

@ -1225,7 +1225,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
*gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
<< QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
<< QModifKeyName(Qt::ALT, QLatin1String("alt+"))
<< QModifKeyName(Qt::META, QLatin1String("meta+"));
<< QModifKeyName(Qt::META, QLatin1String("meta+"))
<< QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+"));
}
} else {
gmodifs = globalPortableModifs();
@ -1233,7 +1234,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
*gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
<< QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
<< QModifKeyName(Qt::ALT, QLatin1String("alt+"))
<< QModifKeyName(Qt::META, QLatin1String("meta+"));
<< QModifKeyName(Qt::META, QLatin1String("meta+"))
<< QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+"));
}
}
if (!gmodifs) return ret;
@ -1244,7 +1246,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::ALT, QCoreApplication::translate("QShortcut", "Alt").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+')));
<< QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::KeypadModifier, QCoreApplication::translate("QShortcut", "Numpad").toLower().append(QLatin1Char('+')));
}
modifs += *gmodifs; // Test non-translated ones last
@ -1418,10 +1421,12 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format);
if ((key & Qt::SHIFT) == Qt::SHIFT)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format);
if ((key & Qt::KeypadModifier) == Qt::KeypadModifier)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Numpad") : QString::fromLatin1("Numpad"), format);
}
key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier);
QString p;
if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {

View File

@ -759,7 +759,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
return false;
if (surface->surfaceType() != QSurface::OpenGLSurface) {
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface";
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface;
return false;
}

View File

@ -873,6 +873,14 @@ bool QWindow::isExposed() const
return d->exposed;
}
/*!
\property QWindow::active
\brief the active status of the window
\since 5.1
\sa requestActivate()
*/
/*!
Returns true if the window should appear active from a style perspective.

View File

@ -115,6 +115,7 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged REVISION 1)
Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged REVISION 1)
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged REVISION 1)
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged REVISION 1)
Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged REVISION 1)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1)
@ -170,8 +171,6 @@ public:
void setMask(const QRegion &region);
QRegion mask() const;
void requestActivate();
bool isActive() const;
void reportContentOrientationChange(Qt::ScreenOrientation orientation);
@ -264,6 +263,8 @@ public:
static QWindow *fromWinId(WId id);
public Q_SLOTS:
Q_REVISION(1) void requestActivate();
void setVisible(bool visible);
void show();
@ -310,6 +311,7 @@ Q_SIGNALS:
void visibleChanged(bool arg);
Q_REVISION(1) void visibilityChanged(QWindow::Visibility visibility);
Q_REVISION(1) void activeChanged();
Q_REVISION(1) void contentOrientationChanged(Qt::ScreenOrientation orientation);
void focusObjectChanged(QObject *object);

View File

@ -140,11 +140,11 @@ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &new
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
{
if (tlw) {
QWindowSystemInterfacePrivate::CloseEvent *e =
new QWindowSystemInterfacePrivate::CloseEvent(tlw);
new QWindowSystemInterfacePrivate::CloseEvent(tlw, accepted);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
}

View File

@ -131,7 +131,7 @@ public:
static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleGeometryChange(QWindow *w, const QRect &newRect);
static void handleCloseEvent(QWindow *w);
static void handleCloseEvent(QWindow *w, bool *accepted = 0);
static void handleEnterEvent(QWindow *w, const QPointF &local = QPointF(), const QPointF& global = QPointF());
static void handleLeaveEvent(QWindow *w);
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF());

View File

@ -105,9 +105,11 @@ public:
class CloseEvent : public WindowSystemEvent {
public:
explicit CloseEvent(QWindow *w)
: WindowSystemEvent(Close), window(w) { }
explicit CloseEvent(QWindow *w, bool *a = 0)
: WindowSystemEvent(Close), window(w), accepted(a)
{ }
QPointer<QWindow> window;
bool *accepted;
};
class GeometryChangeEvent : public WindowSystemEvent {

View File

@ -42,6 +42,8 @@
#ifndef QOPENGLTIMERQUERY_H
#define QOPENGLTIMERQUERY_H
#include <QtCore/qglobal.h>
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
#include <QtCore/QObject>

View File

@ -42,6 +42,8 @@
#ifndef QOPENGLVERTEXARRAYOBJECT_H
#define QOPENGLVERTEXARRAYOBJECT_H
#include <QtCore/qglobal.h>
#ifndef QT_NO_OPENGL
#include <QtCore/QObject>

View File

@ -92,7 +92,7 @@ static res_state_ptr local_res = 0;
static void resolveLibrary()
{
#ifndef QT_NO_LIBRARY
#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX)
QLibrary lib(QLatin1String("resolv"));
if (!lib.load())
return;

View File

@ -55,7 +55,11 @@ QT_BEGIN_NAMESPACE
static bool ignoreProxyFor(const QNetworkProxyQuery &query)
{
const QList<QByteArray> noProxyTokens = qgetenv("no_proxy").split(',');
const QByteArray noProxy = qgetenv("no_proxy").trimmed();
if (noProxy.isEmpty())
return false;
const QList<QByteArray> noProxyTokens = noProxy.split(',');
foreach (const QByteArray &rawToken, noProxyTokens) {
QByteArray token = rawToken.trimmed();

View File

@ -1908,6 +1908,7 @@ QSslSocketPrivate::QSslSocketPrivate()
, mode(QSslSocket::UnencryptedMode)
, autoStartHandshake(false)
, connectionEncrypted(false)
, shutdown(false)
, ignoreAllSslErrors(false)
, readyReadEmittedPointer(0)
, allowRootCertOnDemandLoading(true)
@ -1933,6 +1934,7 @@ void QSslSocketPrivate::init()
autoStartHandshake = false;
connectionEncrypted = false;
ignoreAllSslErrors = false;
shutdown = false;
// we don't want to clear the ignoreErrorsList, so
// that it is possible setting it before connecting

View File

@ -934,8 +934,11 @@ void QSslSocketBackendPrivate::transmit()
#ifdef QSSLSOCKET_DEBUG
qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect";
#endif
plainSocket->disconnectFromHost();
break;
shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
q->setErrorString(QSslSocket::tr("The TLS/SSL connection has been closed"));
q->setSocketError(QAbstractSocket::RemoteHostClosedError);
emit q->error(QAbstractSocket::RemoteHostClosedError);
return;
case SSL_ERROR_SYSCALL: // some IO error
case SSL_ERROR_SSL: // error in the SSL library
// we do not know exactly what the error is, nor whether we can recover from it,
@ -1369,8 +1372,11 @@ void QWindowsCaRootFetcher::start()
void QSslSocketBackendPrivate::disconnectFromHost()
{
if (ssl) {
q_SSL_shutdown(ssl);
transmit();
if (!shutdown) {
q_SSL_shutdown(ssl);
shutdown = true;
transmit();
}
}
plainSocket->disconnectFromHost();
}

View File

@ -109,6 +109,7 @@ public:
QSslSocket::SslMode mode;
bool autoStartHandshake;
bool connectionEncrypted;
bool shutdown;
bool ignoreAllSslErrors;
QList<QSslError> ignoreErrorsList;
bool* readyReadEmittedPointer;

View File

@ -1,7 +1,7 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
# Name of the project which must match the outputdir. Determines the .index file
project = qtopengl
project = QtOpenGL
# Directories in which to search for files to document and images.
# By default set to the root directory of the project for sources
@ -32,23 +32,23 @@ examplesinstallpath = opengl
# Defines the name of the project. You cannot use operators (+, =, -) in
# the name. Properties for this project are set using a qhp.<projectname>.property
# format.
qhp.projects = qtopengl
qhp.projects = QtOpenGL
# Sets the name of the output qhp file.
qhp.qtopengl.file = qtopengl.qhp
qhp.QtOpenGL.file = qtopengl.qhp
# Namespace for the output file. This namespace is used to distinguish between
# different documentation files in Creator/Assistant.
qhp.qtopengl.namespace = org.qt-project.qtopengl.$QT_VERSION_TAG
qhp.QtOpenGL.namespace = org.qt-project.qtopengl.$QT_VERSION_TAG
# Title for the package, will be the main title for the package in
# Assistant/Creator.
qhp.qtopengl.indexTitle = Qt OpenGL
qhp.QtOpenGL.indexTitle = Qt OpenGL
# Only update the name of the project for the next variables.
qhp.qtopengl.virtualFolder = qtopengl
qhp.qtopengl.subprojects = classes
qhp.qtopengl.subprojects.classes.title = C++ Classes
qhp.qtopengl.subprojects.classes.indexTitle = Qt OpenGL C++ Classes
qhp.qtopengl.subprojects.classes.selectors = class fake:headerfile
qhp.qtopengl.subprojects.classes.sortPages = true
qhp.QtOpenGL.virtualFolder = qtopengl
qhp.QtOpenGL.subprojects = classes
qhp.QtOpenGL.subprojects.classes.title = C++ Classes
qhp.QtOpenGL.subprojects.classes.indexTitle = Qt OpenGL C++ Classes
qhp.QtOpenGL.subprojects.classes.selectors = class fake:headerfile
qhp.QtOpenGL.subprojects.classes.sortPages = true

View File

@ -146,10 +146,15 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
if (widget->testAttribute(Qt::WA_TranslucentBackground))
winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8));
if (!widget->windowHandle()->handle()) {
widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
widget->windowHandle()->setFormat(winFormat);
widget->winId();//make window
QWindow *window = widget->windowHandle();
if (!window->handle()
|| window->surfaceType() != QWindow::OpenGLSurface
|| window->requestedFormat() != winFormat)
{
window->setSurfaceType(QWindow::OpenGLSurface);
window->setFormat(winFormat);
window->destroy();
window->create();
}
if (d->ownContext)

View File

@ -47,11 +47,17 @@
#include <QtCore/QElapsedTimer>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
#include <QtGui/private/qfontengine_ft_p.h>
#include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qfontengine_qpa_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qguiapplication.h>
#include <ft2build.h>
#include FT_TRUETYPE_TABLES_H
@ -640,6 +646,19 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
break;
}
}
if (f.hintingPreference == QFont::PreferDefaultHinting) {
QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment();
if (desktopEnvironment == "GNOME" || desktopEnvironment == "UNITY") {
void *hintStyleResource =
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
QGuiApplication::primaryScreen());
int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
if (hintStyle > 0)
default_hint_style = QFontEngine::HintStyle(hintStyle - 1);
}
}
engine->setDefaultHintStyle(default_hint_style);
if (antialias) {

View File

@ -104,6 +104,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons
int repeatRate = 80;
bool disableZap = false;
bool enableCompose = false;
int grab = 0;
QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) {
@ -117,6 +118,8 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons
repeatDelay = arg.mid(13).toInt();
else if (arg.startsWith(QLatin1String("repeat-rate=")))
repeatRate = arg.mid(12).toInt();
else if (arg.startsWith(QLatin1String("grab=")))
grab = arg.mid(5).toInt();
}
#ifdef QT_QPA_KEYMAP_DEBUG
@ -126,6 +129,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons
int fd;
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (fd >= 0) {
::ioctl(fd, EVIOCGRAB, grab);
if (repeatDelay > 0 && repeatRate > 0) {
int kbdrep[2] = { repeatDelay, repeatRate };
::ioctl(fd, EVIOCSREP, kbdrep);

View File

@ -70,6 +70,7 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
bool compression = true;
int jitterLimit = 0;
int grab = 0;
QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) {
@ -77,11 +78,14 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
compression = false;
else if (arg.startsWith(QLatin1String("dejitter=")))
jitterLimit = arg.mid(9).toInt();
else if (arg.startsWith(QLatin1String("grab=")))
grab = arg.mid(5).toInt();
}
int fd;
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (fd >= 0) {
::ioctl(fd, EVIOCGRAB, grab);
return new QEvdevMouseHandler(device, fd, compression, jitterLimit);
} else {
qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno));

View File

@ -120,6 +120,8 @@ QHeaderView *QAccessibleTable::horizontalHeader() const
#ifndef QT_NO_TREEVIEW
} else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view())) {
header = tv->header();
if (header && header->isHidden())
header = 0;
#endif
}
return header;
@ -766,7 +768,6 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
int column = cell->m_index.column();
int index = row * view()->model()->columnCount() + column;
Q_ASSERT(index >= treeView->model()->columnCount());
return index;
} else if (iface->role() == QAccessible::ColumnHeader){
const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);

View File

@ -206,7 +206,7 @@ int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const
bool QAccessibleMenuItem::isValid() const
{
return m_action ? true : false;
return m_action && m_owner ? true : false;
}
QAccessibleInterface *QAccessibleMenuItem::parent() const

View File

@ -43,6 +43,7 @@
#define QACCESSIBLEMENU_H
#include <QtWidgets/private/qaccessiblewidget_p.h>
#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@ -120,7 +121,7 @@ protected:
QAction *action() const;
private:
QAction *m_action;
QWidget *m_owner; // can hold either QMenu or the QMenuBar that contains the action
QPointer<QWidget> m_owner; // can hold either QMenu or the QMenuBar that contains the action
};
#endif // QT_NO_MENU

View File

@ -1127,7 +1127,7 @@ QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
QAccessibleInterface *QAccessibleMainWindow::child(int index) const
{
QList<QWidget*> kids = childWidgets(mainWindow(), true);
if (index < kids.count()) {
if (index >= 0 && index < kids.count()) {
return QAccessible::queryAccessibleInterface(kids.at(index));
}
return 0;

View File

@ -280,8 +280,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym)
qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
.arg(codec->toUnicode(chars));
#endif
const QChar *ch = QString(chars.data()).unicode();
return ch->unicode();
return QString::fromUtf8(chars).at(0).unicode();
}
quint32 TableGenerator::stringToKeysym(QString keysymName)

View File

@ -183,7 +183,6 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
{
delete m_androidPlatformNativeInterface;
delete m_androidFDB;
delete m_touchDevice;
QtAndroid::setAndroidPlatformIntegration(NULL);
}
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const

View File

@ -41,6 +41,8 @@ OBJECTIVE_SOURCES += main.mm \
qcocoaintrospection.mm \
qcocoakeymapper.mm \
SOURCES += messages.cpp
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
qcocoabackingstore.h \
@ -75,6 +77,7 @@ HEADERS += qcocoaintegration.h \
qcocoasystemtrayicon.h \
qcocoaintrospection.h \
qcocoakeymapper.h \
messages.h
RESOURCES += qcocoaresources.qrc

View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "messages.h"
#include <QCoreApplication>
// Translatable messages should go into this .cpp file for them to be picked up by lupdate.
QT_BEGIN_NAMESPACE
QString msgAboutQt()
{
return QCoreApplication::translate("QCocoaMenuItem", "About Qt");
}
static const char *application_menu_strings[] =
{
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
};
QString qt_mac_applicationmenu_string(int type)
{
QString menuString = QString::fromLatin1(application_menu_strings[type]);
const QString translated = QCoreApplication::translate("QMenuBar", application_menu_strings[type]);
if (translated != menuString) {
return translated;
} else {
return QCoreApplication::translate("MAC_APPLICATION_MENU", application_menu_strings[type]);
}
}
QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
{
const QString aboutString = QCoreApplication::translate("QCocoaMenuItem", "About");
if (caption.startsWith(aboutString, Qt::CaseInsensitive) || caption.endsWith(aboutString, Qt::CaseInsensitive))
return QPlatformMenuItem::AboutRole;
if (caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Config"), Qt::CaseInsensitive)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Preference"), Qt::CaseInsensitive)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Options"), Qt::CaseInsensitive)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Setting"), Qt::CaseInsensitive)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Setup"), Qt::CaseInsensitive)) {
return QPlatformMenuItem::PreferencesRole;
}
if (caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Quit"), Qt::CaseInsensitive)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Exit"), Qt::CaseInsensitive)) {
return QPlatformMenuItem::QuitRole;
}
return QPlatformMenuItem::NoRole;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MESSAGES_H
#define MESSAGES_H
#include <QString>
#include <qpa/qplatformmenu.h>
QT_BEGIN_NAMESPACE
QString msgAboutQt();
QString qt_mac_applicationmenu_string(int type);
QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption);
QT_END_NAMESPACE
#endif // MESSAGES_H

View File

@ -165,8 +165,11 @@ NSString *macRole(QAccessibleInterface *interface)
return roleMap[qtRole];
}
// MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityUnknownRole";
return NSAccessibilityUnknownRole;
// Treat unknown Qt roles as generic group container items. Returning
// NSAccessibilityUnknownRole is also possible but makes the screen
// reader focus on the item instead of passing focus to child items.
// MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityGroupRole for unknown Qt role";
return NSAccessibilityGroupRole;
}
/*

View File

@ -199,14 +199,14 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
#endif
const uchar *cursorData = 0;
const uchar *cursorMaskData = 0;
QPoint hotspot;
QPoint hotspot = cursor->hotSpot();
switch (cursor->shape()) {
case Qt::BitmapCursor: {
if (cursor->pixmap().isNull())
return createCursorFromBitmap(cursor->bitmap(), cursor->mask());
return createCursorFromBitmap(cursor->bitmap(), cursor->mask(), hotspot);
else
return createCursorFromPixmap(cursor->pixmap());
return createCursorFromPixmap(cursor->pixmap(), hotspot);
break; }
case Qt::BlankCursor: {
QPixmap pixmap = QPixmap(16, 16);
@ -215,19 +215,19 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
break; }
case Qt::WaitCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/spincursor.png"));
return createCursorFromPixmap(pixmap);
return createCursorFromPixmap(pixmap, hotspot);
break; }
case Qt::SizeAllCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png"));
return createCursorFromPixmap(pixmap);
return createCursorFromPixmap(pixmap, hotspot);
break; }
case Qt::BusyCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png"));
return createCursorFromPixmap(pixmap);
return createCursorFromPixmap(pixmap, hotspot);
break; }
case Qt::ForbiddenCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png"));
return createCursorFromPixmap(pixmap);
return createCursorFromPixmap(pixmap, hotspot);
break; }
#define QT_USE_APPROXIMATE_CURSORS
#ifdef QT_USE_APPROXIMATE_CURSORS

View File

@ -47,10 +47,6 @@
#include <qpa/qplatformmenu.h>
#include "qcocoamenuitem.h"
@class NSMenuItem;
@class NSMenu;
@class NSObject;
QT_BEGIN_NAMESPACE
class QCocoaMenu : public QPlatformMenu
@ -81,8 +77,6 @@ public:
void setMinimumWidth(int width);
void setFont(const QFont &font);
void setParentItem(QCocoaMenuItem* item);
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
inline NSMenuItem *nsMenuItem() const
@ -91,6 +85,7 @@ public:
virtual QPlatformMenuItem *menuItemAt(int position) const;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const;
QList<QCocoaMenuItem *> items() const;
QList<QCocoaMenuItem *> merged() const;
private:
QCocoaMenuItem *itemOrNull(int index) const;

View File

@ -45,11 +45,34 @@
#include "qcocoaautoreleasepool.h"
#include <QtCore/QtDebug>
#include <QtCore/private/qthread_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include "qcocoaapplication.h"
#include "qcocoamenuloader.h"
#include "qcocoawindow.h"
#import "qnsview.h"
NSString *qt_mac_removePrivateUnicode(NSString* string)
{
int len = [string length];
if (len) {
QVarLengthArray <unichar, 10> characters(len);
bool changed = false;
for (int i = 0; i<len; i++) {
characters[i] = [string characterAtIndex:i];
// check if they belong to key codes in private unicode range
// currently we need to handle only the NSDeleteFunctionKey
if (characters[i] == NSDeleteFunctionKey) {
characters[i] = NSDeleteCharacter;
changed = true;
}
}
if (changed)
return [NSString stringWithCharacters:characters.data() length:len];
}
return string;
}
static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
@ -89,6 +112,7 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
- (void) itemFired:(NSMenuItem*) item
{
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData);
cocoaItem->activated();
}
@ -101,6 +125,80 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
return cocoaItem->isEnabled();
}
- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action
{
/*
Check if the menu actually has a keysequence defined for this key event.
If it does, then we will first send the key sequence to the QWidget that has focus
since (in Qt's eyes) it needs to a chance at the key event first (QEvent::ShortcutOverride).
If the widget accepts the key event, we then return YES, but set the target and action to be nil,
which means that the action should not be triggered, and instead dispatch the event ourselves.
In every other case we return NO, which means that Cocoa can do as it pleases
(i.e., fire the menu action).
*/
// Change the private unicode keys to the ones used in setting the "Key Equivalents"
NSString *characters = qt_mac_removePrivateUnicode([event characters]);
if ([self hasShortcut:menu
forKey:characters
// Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ...
forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask))
]) {
QObject *object = qApp->focusObject();
if (object) {
QChar ch;
int keyCode;
ulong nativeModifiers = [event modifierFlags];
Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers];
NSString *characters = [event characters];
if ([charactersIgnoringModifiers length] > 0) { // convert the first character into a key code
if ((modifiers & Qt::ControlModifier) && ([characters length] != 0)) {
ch = QChar([characters characterAtIndex:0]);
} else {
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
}
keyCode = qt_mac_cocoaKey2QtKey(ch);
} else {
// might be a dead key
ch = QChar::ReplacementCharacter;
keyCode = Qt::Key_unknown;
}
QKeyEvent accel_ev(QEvent::ShortcutOverride, (keyCode & (~Qt::KeyboardModifierMask)),
Qt::KeyboardModifiers(keyCode & Qt::KeyboardModifierMask));
accel_ev.ignore();
QCoreApplication::sendEvent(object, &accel_ev);
if (accel_ev.isAccepted()) {
[[NSApp keyWindow] sendEvent: event];
*target = nil;
*action = nil;
return YES;
}
}
}
return NO;
}
- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
{
for (NSMenuItem *item in [menu itemArray]) {
if (![item isEnabled] || [item isHidden] || [item isSeparatorItem])
continue;
if ([item hasSubmenu]
&& [self hasShortcut:[item submenu] forKey:key forModifiers:modifier])
return YES;
NSString *menuKey = [item keyEquivalent];
if (menuKey
&& NSOrderedSame == [menuKey compare:key]
&& modifier == [item keyEquivalentModifierMask])
return YES;
}
return NO;
}
@end
QT_BEGIN_NAMESPACE
@ -154,6 +252,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
menuItem->setParent(this);
cocoaItem->sync();
if (beforeItem) {
int index = m_menuItems.indexOf(beforeItem);
@ -209,6 +308,10 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed";
return;
}
if (menuItem->parent() == this)
menuItem->setParent(0);
m_menuItems.removeOne(cocoaItem);
if (!cocoaItem->isMerged()) {
if (m_nativeMenu != [cocoaItem->nsItem() menu]) {
@ -266,8 +369,12 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
NSArray *itemArray = [m_nativeMenu itemArray];
for (unsigned int i = 0; i < [itemArray count]; ++i) {
NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
if ([item isSeparatorItem])
if ([item isSeparatorItem]) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
if (cocoaItem)
cocoaItem->setVisible(!previousIsSeparator);
[item setHidden:previousIsSeparator];
}
if (![item isHidden]) {
previousItem = item;
@ -276,8 +383,12 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
}
// We now need to check the final item since we don't want any separators at the end of the list.
if (previousItem && previousIsSeparator)
if (previousItem && previousIsSeparator) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([previousItem tag]);
if (cocoaItem)
cocoaItem->setVisible(false);
[previousItem setHidden:YES];
}
} else {
foreach (QCocoaMenuItem *item, m_menuItems) {
if (!item->isSeparator())
@ -289,11 +400,6 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
}
}
void QCocoaMenu::setParentItem(QCocoaMenuItem *item)
{
Q_UNUSED(item);
}
void QCocoaMenu::setEnabled(bool enabled)
{
m_enabled = enabled;
@ -378,6 +484,11 @@ QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const
return 0;
}
QList<QCocoaMenuItem *> QCocoaMenu::items() const
{
return m_menuItems;
}
QList<QCocoaMenuItem *> QCocoaMenu::merged() const
{
QList<QCocoaMenuItem *> result;

View File

@ -47,14 +47,13 @@
#include <qpa/qplatformmenu.h>
#include "qcocoamenu.h"
@class NSMenu;
QT_BEGIN_NAMESPACE
class QCocoaWindow;
class QCocoaMenuBar : public QPlatformMenuBar
{
Q_OBJECT
public:
QCocoaMenuBar();
virtual ~QCocoaMenuBar();

View File

@ -109,6 +109,8 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
[m_nativeMenu addItem: menu->nsMenuItem()];
}
platformMenu->setParent(this);
syncMenu(platformMenu);
[m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
}
@ -123,13 +125,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
}
m_menus.removeOne(menu);
if (platformMenu->parent() == this)
platformMenu->setParent(0);
NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
[m_nativeMenu removeItemAtIndex: realIndex];
}
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
{
Q_UNUSED(menu);
QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(menu);
Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items())
cocoaMenu->syncMenuItem(item);
}
void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)

View File

@ -48,8 +48,16 @@
//#define QT_COCOA_ENABLE_MENU_DEBUG
@class NSMenuItem;
@class NSMenu;
#ifdef __OBJC__
#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) @class __KLASS__
#else
#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) typedef struct objc_object __KLASS__
#endif
QT_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem);
QT_FORWARD_DECLARE_OBJC_CLASS(NSMenu);
QT_FORWARD_DECLARE_OBJC_CLASS(NSObject);
QT_BEGIN_NAMESPACE
@ -96,6 +104,7 @@ private:
NSMenuItem *m_native;
QString m_text;
bool m_textSynced;
QIcon m_icon;
QCocoaMenu *m_menu;
bool m_isVisible;

View File

@ -42,6 +42,8 @@
#include "qcocoamenuitem.h"
#include "qcocoamenu.h"
#include "qcocoamenubar.h"
#include "messages.h"
#include "qcocoahelpers.h"
#include "qcocoaautoreleasepool.h"
#include "qt_mac_p.h"
@ -89,6 +91,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel)
QCocoaMenuItem::QCocoaMenuItem() :
m_native(NULL),
m_textSynced(false),
m_menu(NULL),
m_isVisible(true),
m_enabled(true),
@ -123,11 +126,13 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
{
if (menu == m_menu)
return;
if (m_menu && m_menu->parent() == this)
m_menu->setParent(0);
QCocoaAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
m_menu->setParentItem(this);
m_menu->setParent(this);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
@ -153,6 +158,8 @@ void QCocoaMenuItem::setFont(const QFont &font)
void QCocoaMenuItem::setRole(MenuRole role)
{
if (role != m_role)
m_textSynced = false; // Changing role deserves a second chance.
m_role = role;
}
@ -190,7 +197,7 @@ NSMenuItem *QCocoaMenuItem::sync()
}
}
if ((m_role != NoRole) || m_merged) {
if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil;
QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
switch (m_role) {
@ -210,25 +217,33 @@ NSMenuItem *QCocoaMenuItem::sync()
mergeItem = [loader preferencesMenuItem];
break;
case TextHeuristicRole: {
QString aboutString = tr("About").toLower();
if (m_text.startsWith(aboutString, Qt::CaseInsensitive)
|| m_text.endsWith(aboutString, Qt::CaseInsensitive))
{
QObject *p = parent();
int depth = 1;
QCocoaMenuBar *menubar = 0;
while (depth < 3 && p && !(menubar = qobject_cast<QCocoaMenuBar *>(p))) {
++depth;
p = p->parent();
}
if (depth == 3 || !menubar)
break; // Menu item too deep in the hierarchy, or not connected to any menubar
switch (detectMenuRole(m_text)) {
case QPlatformMenuItem::AboutRole:
if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1)
mergeItem = [loader aboutMenuItem];
else
mergeItem = [loader aboutQtMenuItem];
} else if (m_text.startsWith(tr("Config"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Preference"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Options"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Setting"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Setup"), Qt::CaseInsensitive)) {
break;
case QPlatformMenuItem::PreferencesRole:
mergeItem = [loader preferencesMenuItem];
} else if (m_text.startsWith(tr("Quit"), Qt::CaseInsensitive)
|| m_text.startsWith(tr("Exit"), Qt::CaseInsensitive)) {
break;
case QPlatformMenuItem::QuitRole:
mergeItem = [loader quitMenuItem];
break;
default:
m_textSynced = true;
break;
}
break;
}
@ -237,6 +252,7 @@ NSMenuItem *QCocoaMenuItem::sync()
}
if (mergeItem) {
m_textSynced = true;
m_merged = true;
[mergeItem retain];
[m_native release];
@ -248,6 +264,8 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native = nil; // create item below
m_merged = false;
}
} else {
m_textSynced = true; // NoRole, and that was set explicitly. So, nothing to do anymore.
}
if (!m_native) {
@ -257,23 +275,11 @@ NSMenuItem *QCocoaMenuItem::sync()
[m_native setTag:reinterpret_cast<NSInteger>(this)];
}
// [m_native setHidden:YES];
// [m_native setHidden:NO];
[m_native setHidden: !m_isVisible];
[m_native setEnabled: m_enabled];
QString text = m_text;
QKeySequence accel = m_shortcut;
{
int st = text.lastIndexOf(QLatin1Char('\t'));
if (st != -1) {
accel = QKeySequence(text.right(text.length()-(st+1)));
text.remove(st, text.length()-st);
}
}
text = mergeText();
accel = mergeAccel();
QString text = mergeText();
QKeySequence accel = mergeAccel();
// Show multiple key sequences as part of the menu text.
if (accel.count() > 1)
@ -323,7 +329,7 @@ QString QCocoaMenuItem::mergeText()
return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName());
} else if (m_native== [loader aboutQtMenuItem]) {
if (m_text == QString("About Qt"))
return tr("About Qt");
return msgAboutQt();
else
return m_text;
} else if (m_native == [loader preferencesMenuItem]) {

View File

@ -41,15 +41,18 @@
#include "qcocoamenuloader.h"
#include "messages.h"
#include "qcocoahelpers.h"
#include "qcocoamenubar.h"
#include "qcocoamenuitem.h"
#include <QtCore/private/qcore_mac_p.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtCore/qstring.h>
#include <QtCore/qdebug.h>
#include <QtGui/private/qguiapplication_p.h>
QT_FORWARD_DECLARE_CLASS(QCFString)
QT_FORWARD_DECLARE_CLASS(QString)
@ -57,30 +60,6 @@ QT_FORWARD_DECLARE_CLASS(QString)
QT_BEGIN_NAMESPACE
#ifndef QT_NO_TRANSLATION
static const char *application_menu_strings[] = {
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
};
QString qt_mac_applicationmenu_string(int type)
{
QString menuString = QString::fromLatin1(application_menu_strings[type]);
QString translated = qApp->translate("QMenuBar", application_menu_strings[type]);
if (translated != menuString) {
return translated;
} else {
return qApp->translate("MAC_APPLICATION_MENU",
application_menu_strings[type]);
}
}
#endif
/*
Loads and instantiates the main app menu from the menu nib file(s).
@ -328,6 +307,7 @@ QT_END_NAMESPACE
if ([item tag]) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData);
cocoaItem->activated();
}
}

View File

@ -65,6 +65,8 @@ public:
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
Q_INVOKABLE void beep();
static void *cglContextForContext(QOpenGLContext *context);
static void *nsOpenGLContextForContext(QOpenGLContext* context);
@ -113,6 +115,9 @@ private:
// Embedding NSViews as child QWindows
static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView);
// Set a QWindow as a "guest" (subwindow) of a non-QWindow
static void setEmbeddedInForeignView(QPlatformWindow *window, bool embedded);
// Register if a window should deliver touch events. Enabling
// touch events has implications for delivery of other events,
// for example by causing scrolling event lag.

View File

@ -120,10 +120,17 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView);
if (resource.toLower() == "registertouchwindow")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
if (resource.toLower() == "setembeddedinforeignview")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
return 0;
}
void QCocoaNativeInterface::beep()
{
NSBeep();
}
QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
{
#ifndef QT_NO_WIDGETS
@ -224,8 +231,17 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *
cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView));
}
void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded)
{
QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window);
cocoaPlatformWindow->setEmbeddedInForeignView(embedded);
}
void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
{
if (!window)
return;
// Make sure the QCocoaWindow is created when enabling. Disabling might
// happen on window destruction, don't (re)create the QCocoaWindow then.
if (enable)

View File

@ -106,6 +106,8 @@ public:
void setWindowTitle(const QString &title);
void setWindowFilePath(const QString &filePath);
void setWindowIcon(const QIcon &icon);
void setAlertState(bool enabled);
bool isAlertState() const;
void raise();
void lower();
bool isExposed() const;
@ -125,10 +127,12 @@ public:
NSView *contentView() const;
void setContentView(NSView *contentView);
void setEmbeddedInForeignView(bool subwindow);
void windowWillMove();
void windowDidMove();
void windowDidResize();
void windowWillClose();
bool windowShouldClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
NSInteger windowLevel(Qt::WindowFlags flags);
@ -173,7 +177,10 @@ public: // for QNSView
NSView *m_contentView;
QNSView *m_qtView;
NSWindow *m_nsWindow;
bool m_contentViewIsEmbedded; // true if the m_contentView is embedded in a "foregin" NSView hiearchy
// TODO merge to one variable if possible
bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy
bool m_contentViewIsToBeEmbedded; // true if the m_contentView is intended to be embedded in a "foreign" NSView hiearchy
QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags;
@ -190,6 +197,9 @@ public: // for QNSView
bool m_frameStrutEventsEnabled;
bool m_isExposed;
int m_registerTouchCount;
static const int NoAlertRequest;
NSInteger m_alertRequest;
};
QT_END_NAMESPACE

View File

@ -191,10 +191,13 @@ static bool isMouseEvent(NSEvent *ev)
@end
const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
, m_nsWindow(0)
, m_contentViewIsEmbedded(false)
, m_contentViewIsToBeEmbedded(false)
, m_nsWindowDelegate(0)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
@ -205,6 +208,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_frameStrutEventsEnabled(false)
, m_isExposed(false)
, m_registerTouchCount(0)
, m_alertRequest(NoAlertRequest)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@ -406,7 +410,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
if (flags == Qt::Window) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
} else if (flags & Qt::Dialog) {
} else if ((flags & Qt::Dialog) == Qt::Dialog) {
if (window()->modality() == Qt::NonModal)
styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
else
@ -499,6 +503,21 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
}
}
void QCocoaWindow::setAlertState(bool enabled)
{
if (m_alertRequest == NoAlertRequest && enabled) {
m_alertRequest = [NSApp requestUserAttention:NSCriticalRequest];
} else if (m_alertRequest != NoAlertRequest && !enabled) {
[NSApp cancelUserAttentionRequest:m_alertRequest];
m_alertRequest = NoAlertRequest;
}
}
bool QCocoaWindow::isAlertState() const
{
return m_alertRequest != NoAlertRequest;
}
void QCocoaWindow::raise()
{
//qDebug() << "raise" << this;
@ -639,6 +658,12 @@ void QCocoaWindow::setContentView(NSView *contentView)
recreateWindow(parent()); // Adds the content view to parent NSView
}
void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
{
m_contentViewIsToBeEmbedded = embedded;
recreateWindow(0); // destroy what was already created
}
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
@ -662,10 +687,12 @@ void QCocoaWindow::windowDidResize()
[m_qtView updateGeometry];
}
void QCocoaWindow::windowWillClose()
bool QCocoaWindow::windowShouldClose()
{
QWindowSystemInterface::handleCloseEvent(window());
bool accepted = false;
QWindowSystemInterface::handleCloseEvent(window(), &accepted);
QWindowSystemInterface::flushWindowSystemEvents();
return accepted;
}
bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
@ -700,8 +727,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindowDelegate = 0;
}
if (window()->type() == Qt::SubWindow) {
// Subwindows don't have a NSWindow.
if (m_contentViewIsToBeEmbedded) {
// An embedded window doesn't have its own NSWindow.
} else if (!parentWindow) {
// Create a new NSWindow if this is a top-level window.
m_nsWindow = createNSWindow();
@ -866,7 +893,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
// if content view width or height is 0 then the window animations will crash so
// do nothing except set the new state
NSRect contentRect = [contentView() frame];
if (contentRect.size.width < 0 || contentRect.size.height < 0) {
if (contentRect.size.width <= 0 || contentRect.size.height <= 0) {
qWarning() << Q_FUNC_INFO << "invalid window content view size, check your window geometry";
m_synchedWindowState = newState;
return;

View File

@ -107,7 +107,7 @@ QT_END_NAMESPACE
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent;
- (int) convertKeyCode : (QChar)keyCode;
- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
+ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
- (void)keyDown:(NSEvent *)theEvent;
- (void)keyUp:(NSEvent *)theEvent;

View File

@ -172,7 +172,7 @@ static QTouchDevice *touchDevice = 0;
- (void)viewDidMoveToSuperview
{
if (!(m_window->type() & Qt::SubWindow))
if (!(m_platformWindow->m_contentViewIsToBeEmbedded))
return;
if ([self superview]) {
@ -208,7 +208,7 @@ static QTouchDevice *touchDevice = 0;
NSRect rect = [self frame];
NSRect windowRect = [[self window] frame];
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_window->type() & Qt::SubWindow) {
} else if (m_platformWindow->m_contentViewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below
geometry = qt_mac_toQRect([self bounds]);
} else {
@ -229,9 +229,9 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->QPlatformWindow::setGeometry(geometry);
// Don't send the geometry change if the QWindow is designated to be
// embedded in a foregin view hiearchy but has not actually been
// embedded in a foreign view hiearchy but has not actually been
// embedded yet - it's too early.
if ((m_window->type() & Qt::SubWindow) && !m_platformWindow->m_contentViewIsEmbedded)
if (m_platformWindow->m_contentViewIsToBeEmbedded && !m_platformWindow->m_contentViewIsEmbedded)
return;
// Send a geometry change event to Qt, if it's ready to handle events
@ -494,7 +494,7 @@ static QTouchDevice *touchDevice = 0;
QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
nativeDrag->setLastMouseEvent(theEvent, self);
Qt::KeyboardModifiers keyboardModifiers = [self convertKeyModifiers:[theEvent modifierFlags]];
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
}
@ -556,7 +556,7 @@ static QTouchDevice *touchDevice = 0;
[inputManager handleMouseEvent:theEvent];
}
} else {
if ([self convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) {
if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) {
m_buttons |= Qt::RightButton;
m_sendUpAsRightButton = true;
} else {
@ -826,7 +826,7 @@ static QTouchDevice *touchDevice = 0;
if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) {
NSEventPhase phase = [theEvent phase];
if (phase == NSEventPhaseBegan) {
currentWheelModifiers = [self convertKeyModifiers:[theEvent modifierFlags]];
currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
}
QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers);
@ -838,7 +838,7 @@ static QTouchDevice *touchDevice = 0;
#endif
{
QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta,
[self convertKeyModifiers:[theEvent modifierFlags]]);
[QNSView convertKeyModifiers:[theEvent modifierFlags]]);
}
}
#endif //QT_NO_WHEELEVENT
@ -848,7 +848,7 @@ static QTouchDevice *touchDevice = 0;
return qt_mac_cocoaKey2QtKey(keyChar);
}
- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags
+ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags
{
Qt::KeyboardModifiers qtMods =Qt::NoModifier;
if (modifierFlags & NSShiftKeyMask)
@ -868,7 +868,7 @@ static QTouchDevice *touchDevice = 0;
{
ulong timestamp = [nsevent timestamp] * 1000;
ulong nativeModifiers = [nsevent modifierFlags];
Qt::KeyboardModifiers modifiers = [self convertKeyModifiers: nativeModifiers];
Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
NSString *characters = [nsevent characters];
@ -948,7 +948,7 @@ static QTouchDevice *touchDevice = 0;
{
ulong timestamp = [nsevent timestamp] * 1000;
ulong modifiers = [nsevent modifierFlags];
Qt::KeyboardModifiers qmodifiers = [self convertKeyModifiers:modifiers];
Qt::KeyboardModifiers qmodifiers = [QNSView convertKeyModifiers:modifiers];
// calculate the delta and remember the current modifiers for next time
static ulong m_lastKnownModifiers;
@ -1278,7 +1278,7 @@ static QTouchDevice *touchDevice = 0;
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
// update these so selecting move/copy/link works
QGuiApplicationPrivate::modifier_buttons = [self convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {

View File

@ -106,9 +106,27 @@
// Hit a child, forward to child accessible interface.
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
// FIXME: parent could be wrong
QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ];
[accessibleElement autorelease];
return [accessibleElement accessibilityHitTest:point];
}
- (id)accessibilityFocusedUIElement {
if (!m_window->accessibleRoot())
return [super accessibilityFocusedUIElement];
QAccessibleInterface *childInterface = m_window->accessibleRoot()->focusChild();
if (childInterface) {
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
// FIXME: parent could be wrong
QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
[accessibleElement autorelease];
return accessibleElement;
}
// should not happen
return nil;
}
@end

View File

@ -56,6 +56,7 @@
- (void)windowDidResize:(NSNotification *)notification;
- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillClose:(NSNotification *)notification;
- (BOOL)windowShouldClose:(NSNotification *)notification;
@end

View File

@ -80,12 +80,14 @@
}
}
- (void)windowWillClose:(NSNotification *)notification
- (BOOL)windowShouldClose:(NSNotification *)notification
{
Q_UNUSED(notification);
if (m_cocoaWindow) {
m_cocoaWindow->windowWillClose();
return m_cocoaWindow->windowShouldClose();
}
return YES;
}
@end

View File

@ -52,7 +52,6 @@ class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInter
{
public:
QIOSIntegration();
~QIOSIntegration();
bool hasCapability(Capability cap) const;

View File

@ -79,11 +79,6 @@ QIOSIntegration::QIOSIntegration()
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
}
QIOSIntegration::~QIOSIntegration()
{
delete m_touchDevice;
}
bool QIOSIntegration::hasCapability(Capability cap) const
{
switch (cap) {

View File

@ -78,6 +78,10 @@
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
Q_UNUSED(duration);
if (!QCoreApplication::instance())
return; // FIXME: Store orientation for later (?)
Qt::ScreenOrientation orientation = toQtScreenOrientation(UIDeviceOrientation(toInterfaceOrientation));
if (orientation == -1)
return;

View File

@ -77,6 +77,9 @@ public:
int effectiveWidth() const;
int effectiveHeight() const;
bool setMouseGrabEnabled(bool grab) { return grab; }
bool setKeyboardGrabEnabled(bool grab) { return grab; }
WId winId() const { return WId(m_view); };
QList<QWindowSystemInterface::TouchPoint> &touchPoints() { return m_touchPoints; }
@ -96,6 +99,9 @@ private:
void raiseOrLower(bool raise);
void updateWindowLevel();
bool blockedByModal();
inline Qt::WindowType windowType() { return static_cast<Qt::WindowType>(int(window()->flags() & Qt::WindowType_Mask)); }
inline bool windowIsPopup() { return windowType() & Qt::Popup & ~Qt::Window; }
};
QT_END_NAMESPACE

View File

@ -475,15 +475,17 @@ void QIOSWindow::raiseOrLower(bool raise)
void QIOSWindow::updateWindowLevel()
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(window()->flags() & Qt::WindowType_Mask));
Qt::WindowType type = windowType();
if (type == Qt::ToolTip)
m_windowLevel = 120;
else if (window()->flags() & Qt::WindowStaysOnTopHint)
m_windowLevel = 100;
else if (window()->isModal())
m_windowLevel = 40;
else if (type == Qt::Popup)
m_windowLevel = 30;
else if (type & Qt::Popup & ~Qt::Window)
else if (type == Qt::SplashScreen)
m_windowLevel = 20;
else if (type == Qt::Tool)
m_windowLevel = 10;

View File

@ -721,22 +721,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI
if (varChildID.vt != VT_I4)
return E_INVALIDARG;
int childIndex = varChildID.lVal;
QAccessibleInterface *acc = 0;
if (childIndex == 0) {
// Yes, some AT clients (Active Accessibility Object Inspector)
// actually ask for the same object. As a consequence, we need to clone ourselves:
acc = accessible;
} else if (childIndex < 0) {
acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex);
} else {
acc = accessible->child(childIndex - 1);
}
QAccessibleInterface *acc = childPointer(accessible, varChildID);
if (acc) {
*ppdispChild = QWindowsAccessibility::wrap(acc);
return S_OK;
@ -825,7 +810,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT var
QString descr;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
descr = child->text(QAccessible::Description);
@ -850,7 +835,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BST
QString help;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
help = child->text(QAccessible::Help);
@ -909,7 +894,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BST
QString name;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
name = child->text(QAccessible::Name);
@ -952,7 +937,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VAR
QAccessible::Role role;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
role = child->role();
@ -987,7 +972,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA
QAccessible::State state;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
state = child->state();

View File

@ -153,13 +153,23 @@ protected:
return 0;
}
QAccessibleInterface *childPointer(VARIANT varID)
static QAccessibleInterface *childPointer(QAccessibleInterface *parent, VARIANT varID)
{
// -1 since windows API always uses 1 for the first child
QAccessibleInterface *iface = accessibleInterface();
if (iface)
return accessibleInterface()->child(varID.lVal - 1);
return 0;
Q_ASSERT(parent);
QAccessibleInterface *acc = 0;
int childIndex = varID.lVal;
if (childIndex == 0) {
// Yes, some AT clients (Active Accessibility Object Inspector)
// actually ask for the same object. As a consequence, we need to clone ourselves:
acc = parent;
} else if (childIndex < 0) {
acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex);
} else {
acc = parent->child(childIndex - 1);
}
return acc;
}
private:

View File

@ -49,6 +49,10 @@
# define WM_THEMECHANGED 0x031A
#endif
#ifndef GWL_HWNDPARENT
# define GWL_HWNDPARENT (-8)
#endif
/* Complement the definitions and declarations missing
* when using MinGW or older Windows SDKs. */

View File

@ -842,9 +842,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::FocusOutEvent:
handleFocusEvent(et, platformWindow);
return true;
case QtWindows::ShowEvent:
platformWindow->handleShown();
return false; // Indicate transient children should be shown by windows (SW_PARENTOPENING)
case QtWindows::HideEvent:
platformWindow->handleHidden();
return false;// Indicate transient children should be hidden by windows (SW_PARENTCLOSING)

View File

@ -833,6 +833,7 @@ public:
bool hideFiltersDetails() const { return m_hideFiltersDetails; }
void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; }
void setDefaultSuffix(const QString &s);
inline bool hasDefaultSuffix() const { return m_hasDefaultSuffix; }
inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text);
// Return the selected files for tracking in OnSelectionChanged().
@ -857,6 +858,7 @@ public slots:
protected:
explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data);
bool init(const CLSID &clsId, const IID &iid);
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; }
static QString itemPath(IShellItem *item);
static QStringList libraryItemFolders(IShellItem *item);
@ -873,12 +875,13 @@ private:
DWORD m_cookie;
QStringList m_nameFilters;
bool m_hideFiltersDetails;
bool m_hasDefaultSuffix;
QWindowsFileDialogSharedData m_data;
};
QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) :
m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false),
m_data(data)
m_hasDefaultSuffix(false), m_data(data)
{
}
@ -1188,6 +1191,15 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters)
void QWindowsNativeFileDialogBase::setDefaultSuffix(const QString &s)
{
setDefaultSuffixSys(s);
m_hasDefaultSuffix = !s.isEmpty();
}
void QWindowsNativeFileDialogBase::setDefaultSuffixSys(const QString &s)
{
// If this parameter is non-empty, it will be appended by the dialog for the 'Any files'
// filter ('*'). If this parameter is non-empty and the current filter has a suffix,
// the dialog will append the filter's suffix.
wchar_t *wSuffix = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(s.utf16()));
m_fileDialog->SetDefaultExtension(wSuffix);
}
@ -1321,33 +1333,45 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnFileOk(IFileDialog *)
class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase
{
Q_OBJECT
public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data);
virtual QStringList selectedFiles() const;
virtual QStringList dialogResult() const;
private slots:
void slotFilterSelected(const QString &);
};
// Append a suffix from the name filter "Foo files (*.foo;*.bar)"
// unless the file name already has one.
static inline QString appendSuffix(const QString &fileName, const QString &filter)
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
static inline QString suffixFromFilter(const QString &filter)
{
const int lastDot = fileName.lastIndexOf(QLatin1Char('.'));
const int lastSlash = fileName.lastIndexOf(QLatin1Char('/'));
if (lastDot >= 0 && (lastSlash == -1 || lastDot > lastSlash))
return fileName;
int suffixPos = filter.indexOf(QLatin1String("(*."));
if (suffixPos < 0)
return fileName;
return QString();
suffixPos += 3;
int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1);
if (endPos < 0)
endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1);
if (endPos < 0)
endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1);
if (endPos < 0)
return fileName;
return fileName + QLatin1Char('.') + filter.mid(suffixPos, endPos - suffixPos);
return endPos >= 0 ? filter.mid(suffixPos, endPos - suffixPos) : QString();
}
QWindowsNativeSaveFileDialog::QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data)
{
connect(this, &QWindowsNativeFileDialogBase::filterSelected,
this, &QWindowsNativeSaveFileDialog::slotFilterSelected);
}
void QWindowsNativeSaveFileDialog::slotFilterSelected(const QString &filter)
{
// Cause the dialog to append the suffix of the current filter unless a default
// suffix is set (Note: Qt 4.8 sets the selected filter's suffix before
// calling GetSaveFileName()).
if (!hasDefaultSuffix())
setDefaultSuffixSys(suffixFromFilter(filter));
}
QStringList QWindowsNativeSaveFileDialog::dialogResult() const
@ -1355,7 +1379,7 @@ QStringList QWindowsNativeSaveFileDialog::dialogResult() const
QStringList result;
IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
result.push_back(appendSuffix(QWindowsNativeFileDialogBase::itemPath(item), selectedNameFilter()));
result.push_back(QWindowsNativeFileDialogBase::itemPath(item));
return result;
}

View File

@ -839,6 +839,15 @@ QWindowsWindow::~QWindowsWindow()
destroyIcon();
}
void QWindowsWindow::fireExpose(const QRegion &region, bool force)
{
if (region.isEmpty() && !force)
clearFlag(Exposed);
else
setFlag(Exposed);
QWindowSystemInterface::handleExposeEvent(window(), region);
}
void QWindowsWindow::destroyWindow()
{
if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
@ -942,13 +951,19 @@ void QWindowsWindow::setVisible(bool visible)
if (m_data.hwnd) {
if (visible) {
show_sys();
QWindowSystemInterface::handleExposeEvent(window(),
QRect(QPoint(), geometry().size()));
// When the window is layered, we won't get WM_PAINT, and "we" are in control
// over the rendering of the window
// There is nobody waiting for this, so we don't need to flush afterwards.
QWindow *w = window();
if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1)))
fireExpose(QRect(0, 0, w->width(), w->height()));
} else {
if (hasMouseCapture())
setMouseGrabEnabled(false);
hide_sys();
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
fireExpose(QRegion());
}
}
}
@ -998,6 +1013,24 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
return pos;
}
// Update the transient parent for a toplevel window. The concept does not
// really exist on Windows, the relationship is set by passing a parent along with !WS_CHILD
// to window creation or by setting the parent using GWL_HWNDPARENT (as opposed to
// SetParent, which would make it a real child).
void QWindowsWindow::updateTransientParent() const
{
#ifndef Q_OS_WINCE
// Update transient parent.
const HWND oldTransientParent =
GetAncestor(m_data.hwnd, GA_PARENT) == GetDesktopWindow() ? GetAncestor(m_data.hwnd, GA_ROOTOWNER) : HWND(0);
HWND newTransientParent = 0;
if (const QWindow *tp = window()->transientParent())
newTransientParent = QWindowsWindow::handleOf(tp);
if (newTransientParent && newTransientParent != oldTransientParent)
SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, (LONG_PTR)newTransientParent);
#endif // !Q_OS_WINCE
}
// partially from QWidgetPrivate::show_sys()
void QWindowsWindow::show_sys() const
{
@ -1012,19 +1045,22 @@ void QWindowsWindow::show_sys() const
sm = SW_SHOWMINIMIZED;
if (!isVisible())
sm = SW_SHOWMINNOACTIVE;
} else if (state & Qt::WindowMaximized) {
sm = SW_SHOWMAXIMIZED;
// Windows will not behave correctly when we try to maximize a window which does not
// have minimize nor maximize buttons in the window frame. Windows would then ignore
// non-available geometry, and rather maximize the widget to the full screen, minus the
// window frame (caption). So, we do a trick here, by adding a maximize button before
// maximizing the widget, and then remove the maximize button afterwards.
if (flags & Qt::WindowTitleHint &&
!(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
fakedMaximize = TRUE;
setStyle(style() | WS_MAXIMIZEBOX);
}
}
} else {
updateTransientParent();
if (state & Qt::WindowMaximized) {
sm = SW_SHOWMAXIMIZED;
// Windows will not behave correctly when we try to maximize a window which does not
// have minimize nor maximize buttons in the window frame. Windows would then ignore
// non-available geometry, and rather maximize the widget to the full screen, minus the
// window frame (caption). So, we do a trick here, by adding a maximize button before
// maximizing the widget, and then remove the maximize button afterwards.
if (flags & Qt::WindowTitleHint &&
!(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
fakedMaximize = TRUE;
setStyle(style() | WS_MAXIMIZEBOX);
}
} // Qt::WindowMaximized
} // !Qt::WindowMinimized
}
if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool)
sm = SW_SHOWNOACTIVATE;
@ -1094,14 +1130,9 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
}
}
void QWindowsWindow::handleShown()
{
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
}
void QWindowsWindow::handleHidden()
{
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
fireExpose(QRegion());
}
void QWindowsWindow::setGeometry(const QRect &rectIn)
@ -1267,28 +1298,21 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
if (message == WM_ERASEBKGND) // Backing store - ignored.
return true;
PAINTSTRUCT ps;
if (testFlag(OpenGLSurface)) {
// Observed painting problems with Aero style disabled (QTBUG-7865).
if (testFlag(OpenGLDoubleBuffered))
InvalidateRect(hwnd, 0, false);
BeginPaint(hwnd, &ps);
QWindowSystemInterface::handleExposeEvent(window(), QRegion(qrectFromRECT(ps.rcPaint)));
if (!QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
EndPaint(hwnd, &ps);
} else {
BeginPaint(hwnd, &ps);
const QRect updateRect = qrectFromRECT(ps.rcPaint);
// Observed painting problems with Aero style disabled (QTBUG-7865).
if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered))
InvalidateRect(hwnd, 0, false);
if (QWindowsContext::verboseIntegration)
qDebug() << __FUNCTION__ << this << window() << updateRect;
BeginPaint(hwnd, &ps);
QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect));
if (!QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
EndPaint(hwnd, &ps);
}
// If the a window is obscured by another window (such as a child window)
// we still need to send isExposed=true, for compatibility.
// Our tests depend on it.
fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true);
if (!QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
EndPaint(hwnd, &ps);
return true;
}
@ -1366,9 +1390,23 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
}
}
// Return the effective screen for full screen mode in a virtual desktop.
static const QScreen *effectiveScreen(const QWindow *w)
{
QPoint center = w->geometry().center();
if (!w->isTopLevel())
center = w->mapToGlobal(center);
const QScreen *screen = w->screen();
if (!screen->geometry().contains(center))
foreach (const QScreen *sibling, screen->virtualSiblings())
if (sibling->geometry().contains(center))
return sibling;
return screen;
}
bool QWindowsWindow::isFullScreen_sys() const
{
return geometry_sys() == window()->screen()->geometry();
return geometry_sys() == effectiveScreen(window())->geometry();
}
/*!
@ -1444,7 +1482,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
newStyle |= WS_VISIBLE;
setStyle(newStyle);
const QRect r = window()->screen()->geometry();
const QRect r = effectiveScreen(window())->geometry();
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent);

View File

@ -133,7 +133,8 @@ public:
WithinSetStyle = 0x800,
WithinDestroy = 0x1000,
TouchRegistered = 0x2000,
AlertState = 0x4000
AlertState = 0x4000,
Exposed = 0x08000
};
struct WindowData
@ -161,7 +162,7 @@ public:
virtual void setVisible(bool visible);
bool isVisible() const;
virtual bool isExposed() const { return m_windowState != Qt::WindowMinimized && isVisible(); }
virtual bool isExposed() const { return testFlag(Exposed); }
virtual bool isActive() const;
virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
@ -217,7 +218,6 @@ public:
void handleMoved();
void handleResized(int wParam);
void handleShown();
void handleHidden();
static inline HWND handleOf(const QWindow *w);
@ -272,12 +272,14 @@ private:
inline bool isFullScreen_sys() const;
inline void setWindowState_sys(Qt::WindowState newState);
inline void setParent_sys(const QPlatformWindow *parent) const;
inline void updateTransientParent() const;
void destroyWindow();
void registerDropSite();
void unregisterDropSite();
void handleGeometryChange();
void handleWindowStateChange(Qt::WindowState state);
inline void destroyIcon();
void fireExpose(const QRegion &region, bool force=false);
mutable WindowData m_data;
mutable unsigned m_flags;

View File

@ -242,8 +242,9 @@ void QXcbConnection::updateScreens()
((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen);
}
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName)
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
: m_connection(0)
, m_canGrabServer(canGrabServer)
, m_primaryScreen(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
@ -344,6 +345,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
m_drag = new QXcbDrag(this);
#endif
m_startupId = qgetenv("DESKTOP_STARTUP_ID");
if (!m_startupId.isNull())
qunsetenv("DESKTOP_STARTUP_ID");
sync();
}
@ -386,28 +391,36 @@ QXcbConnection::~QXcbConnection()
delete m_keyboard;
}
void QXcbConnection::addWindow(xcb_window_t id, QXcbWindow *window)
void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener)
{
m_mapper.insert(id, window);
m_mapper.insert(id, eventListener);
}
void QXcbConnection::removeWindow(xcb_window_t id)
void QXcbConnection::removeWindowEventListener(xcb_window_t id)
{
m_mapper.remove(id);
}
QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
QXcbWindowEventListener *QXcbConnection::windowEventListenerFromId(xcb_window_t id)
{
return m_mapper.value(id, 0);
}
QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
{
QXcbWindowEventListener *listener = m_mapper.value(id, 0);
if (listener)
return listener->toWindow();
return 0;
}
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) { \
handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
platformWindow->handler(e); \
eventListener->handler(e); \
} \
} \
break;
@ -415,10 +428,10 @@ break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \
handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
m_keyboard->handler(m_focusWindow, e); \
m_keyboard->handler(m_focusWindow ? m_focusWindow : eventListener, e); \
} \
} \
break;
@ -948,6 +961,18 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w)
m_focusWindow = w;
}
void QXcbConnection::grabServer()
{
if (m_canGrabServer)
xcb_grab_server(m_connection);
}
void QXcbConnection::ungrabServer()
{
if (m_canGrabServer)
xcb_ungrab_server(m_connection);
}
void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
{
xcb_client_message_event_t event;

View File

@ -80,8 +80,6 @@ class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
namespace QXcbAtom {
enum Atom {
// window-manager <-> client protocols
@ -301,12 +299,36 @@ private:
XcbPollForQueuedEventFunctionPointer m_xcb_poll_for_queued_event;
};
class QXcbWindowEventListener
{
public:
virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; }
virtual void handleExposeEvent(const xcb_expose_event_t *) {}
virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {}
virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {}
virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {}
virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {}
virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {}
virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {}
virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {}
virtual void handleEnterNotifyEvent(const xcb_enter_notify_event_t *) {}
virtual void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *) {}
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
virtual QXcbWindow *toWindow() { return 0; }
};
typedef QHash<xcb_window_t, QXcbWindowEventListener *> WindowMapper;
class QAbstractEventDispatcher;
class QXcbConnection : public QObject
{
Q_OBJECT
public:
QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0);
QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0);
~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
@ -356,8 +378,9 @@ public:
void handleXcbError(xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event);
void addWindow(xcb_window_t id, QXcbWindow *window);
void removeWindow(xcb_window_t id);
void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener);
void removeWindowEventListener(xcb_window_t id);
QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id);
xcb_generic_event_t *checkEvent(int type);
@ -388,6 +411,13 @@ public:
QXcbWindow *focusWindow() const { return m_focusWindow; }
void setFocusWindow(QXcbWindow *);
QByteArray startupId() const { return m_startupId; }
void clearStartupId() { m_startupId.clear(); }
void grabServer();
void ungrabServer();
QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
private slots:
void processXcbEvents();
@ -451,6 +481,7 @@ private:
xcb_connection_t *m_connection;
const xcb_setup_t *m_setup;
bool m_canGrabServer;
QList<QXcbScreen *> m_screens;
int m_primaryScreen;
@ -516,6 +547,8 @@ private:
Qt::MouseButtons m_buttons;
QXcbWindow *m_focusWindow;
QByteArray m_startupId;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))

View File

@ -1160,7 +1160,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
if (desktop_proxy) // *WE* already have one.
return false;
xcb_grab_server(xcb_connection());
connection()->grabServer();
// As per Xdnd4, use XdndProxy
xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window());
@ -1176,7 +1176,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
XCB_ATOM_WINDOW, 32, 1, &proxy_id);
}
xcb_ungrab_server(xcb_connection());
connection()->ungrabServer();
} else {
xdnd_widget = w;
}

Some files were not shown because too many files have changed in this diff Show More