Merge remote-tracking branch 'origin/stable' into dev

Change-Id: I2a54058b64ac69c78b4120fdaf09b96e025a4c6c
This commit is contained in:
Frederik Gladhorn 2013-04-29 14:17:08 +02:00
commit 85e3c53e5c
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 echo Qt will be installed into $QT_INSTALL_PREFIX
fi fi
echo 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 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 The default top-level installation directory is the directory "Qt<version>" in
your home directory, but you can specify another directory (<install_dir>). Each your home directory, but you can specify another directory (<install_dir>). On
Qt version is installed in the <install_dir>/<version> directory. This Windows, however, the default top-level installation directory is "C:\Qt\Qt<version>".
directory contains subdirectories for the Qt libraries (<compiler>), Each Qt version is installed in the <install_dir>/<version> directory. This directory
documentation (doc), and sources (src). The <compiler> directory contains contains subdirectories for the Qt libraries (<compiler>) and sources (Src).
subdirectories for development tools (bin) and examples. The <compiler> directory contains subdirectories for development tools (bin) and
examples.
Starting Development Tools Starting Development Tools
@ -80,25 +81,21 @@ the command line. You can also launch some of them as standalone applications.
For example: For example:
- Qt Assistant, the Qt documentation reader - Qt Assistant, the Qt documentation reader
- qmlscene, the viewer for Qt Quick2 declarative QML applications - Qt QML Scene, the viewer for Qt Quick 2 files
- QMLViewer, the viewer for Qt Quick1 declarative QML applications - Qt QML Viewer, the viewer for Qt Quick 1 files
- Qt Designer, the GUI designer for Qt widgets-based applications 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 Running Example Applications
---------------------------- ----------------------------
You can open example applications in the Qt Creator Welcome mode to build and You can open most example applications in the Qt Creator Welcome mode to build
run them. and run them. Additional examples can be opened by browsing
<install_dir>/<version>/<compiler>/examples.
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.
Building Qt 5 from Source Building Qt 5 from Source
------------------------- -------------------------

View File

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

View File

@ -41,10 +41,13 @@
#include <QWindow> #include <QWindow>
#include <QColor> #include <QColor>
#include <QMutex>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QSharedPointer> #include <QSharedPointer>
#include <QTimer> #include <QTimer>
class HelloWindow;
class Renderer : public QObject class Renderer : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -54,8 +57,10 @@ public:
QSurfaceFormat format() const { return m_format; } QSurfaceFormat format() const { return m_format; }
public slots: void setAnimating(HelloWindow *window, bool animating);
void render(QSurface *surface, const QColor &color, const QSize &viewSize);
private slots:
void render();
private: private:
void initialize(); void initialize();
@ -78,30 +83,28 @@ private:
QSurfaceFormat m_format; QSurfaceFormat m_format;
QOpenGLContext *m_context; QOpenGLContext *m_context;
QOpenGLShaderProgram *m_program; QOpenGLShaderProgram *m_program;
QList<HelloWindow *> m_windows;
int m_currentWindow;
QMutex m_windowLock;
}; };
class HelloWindow : public QWindow class HelloWindow : public QWindow
{ {
Q_OBJECT
public: public:
explicit HelloWindow(const QSharedPointer<Renderer> &renderer); explicit HelloWindow(const QSharedPointer<Renderer> &renderer);
QColor color() const;
void updateColor(); void updateColor();
void exposeEvent(QExposeEvent *event); void exposeEvent(QExposeEvent *event);
signals:
void needRender(QSurface *surface, const QColor &color, const QSize &viewSize);
private slots:
void render();
private: private:
void mousePressEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *);
int m_colorIndex; int m_colorIndex;
QColor m_color; QColor m_color;
const QSharedPointer<Renderer> m_renderer; 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_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON = -qrtti
QMAKE_CXXFLAGS_RTTI_OFF = -qnortti
QMAKE_COMPILER_DEFINES += __xlC__ QMAKE_COMPILER_DEFINES += __xlC__
QMAKE_INCDIR = QMAKE_INCDIR =

View File

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

View File

@ -40,3 +40,26 @@ defineReplace(cmakeTargetPaths) {
} }
return ($$join(out, " ")) 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 -= $$CMAKE_QT_MODULES_UNDER_TEST
dependentmodules = $$cmakeModuleList($$dependentmodules) dependentmodules = $$cmakeModuleList($$dependentmodules)
contains(QT_CONFIG, angle): CMAKE_ANGLE_DEFINE = -DQT_WITH_ANGLE=True
CMAKE_MODULE_VERSIONS = CMAKE_MODULE_VERSIONS =
CMAKE_MODULES_UNDER_TEST = CMAKE_MODULES_UNDER_TEST =
for (MODULE_UNDER_TEST, CMAKE_QT_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 \ cmake $$_PRO_FILE_PWD_ $$CMAKE_GENERATOR \
-DCMAKE_VERBOSE_MAKEFILE=1 \ -DCMAKE_VERBOSE_MAKEFILE=1 \
$$CMAKE_MODULE_DEFINES \ $$CMAKE_MODULE_DEFINES \
$$CMAKE_ANGLE_DEFINE \
-DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \ -DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \
-DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \ -DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \
-DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" \ -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. # Qt modules get compiled without exceptions enabled by default.
# However, testcases should be still built with exceptions. # However, testcases should be still built with exceptions.
exceptions_off testcase_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) bp = $$eval($$upper($$TARGET)_BUILD_PARTS)
!isEmpty(bp): QT_BUILD_PARTS = $$bp !isEmpty(bp): QT_BUILD_PARTS = $$bp
sub_src.subdir = src exists($$_PRO_FILE_PWD_/src/src.pro) {
sub_src.target = sub-src sub_src.subdir = src
SUBDIRS = sub_src sub_src.target = sub-src
SUBDIRS += sub_src
exists($$_PRO_FILE_PWD_/tools/tools.pro) { exists($$_PRO_FILE_PWD_/tools/tools.pro) {
sub_tools.subdir = tools sub_tools.subdir = tools
sub_tools.target = sub-tools sub_tools.target = sub-tools
sub_tools.depends = sub_src sub_tools.depends = sub_src
!contains(QT_BUILD_PARTS, tools): sub_tools.CONFIG = no_default_target no_default_install # conditional treatment happens on a case-by-case basis
SUBDIRS += sub_tools SUBDIRS += sub_tools
}
} }
exists($$_PRO_FILE_PWD_/examples/examples.pro) { exists($$_PRO_FILE_PWD_/examples/examples.pro) {
sub_examples.subdir = examples sub_examples.subdir = examples
sub_examples.target = sub-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 examples_need_tools: sub_examples.depends += sub_tools
!contains(QT_BUILD_PARTS, examples): sub_examples.CONFIG = no_default_target no_default_install !contains(QT_BUILD_PARTS, examples): sub_examples.CONFIG = no_default_target no_default_install
SUBDIRS += sub_examples SUBDIRS += sub_examples
@ -44,7 +46,7 @@ exists($$_PRO_FILE_PWD_/examples/examples.pro) {
exists($$_PRO_FILE_PWD_/demos/demos.pro) { exists($$_PRO_FILE_PWD_/demos/demos.pro) {
sub_demos.subdir = demos sub_demos.subdir = demos
sub_demos.target = sub-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 examples_need_tools: sub_demos.depends += sub_tools
!contains(QT_BUILD_PARTS, examples): sub_demos.CONFIG = no_default_target no_default_install !contains(QT_BUILD_PARTS, examples): sub_demos.CONFIG = no_default_target no_default_install
SUBDIRS += sub_demos SUBDIRS += sub_demos
@ -53,7 +55,7 @@ exists($$_PRO_FILE_PWD_/demos/demos.pro) {
exists($$_PRO_FILE_PWD_/tests/tests.pro) { exists($$_PRO_FILE_PWD_/tests/tests.pro) {
sub_tests.subdir = tests sub_tests.subdir = tests
sub_tests.target = sub-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 tests_need_tools: sub_tests.depends += sub_tools
sub_tests.CONFIG = no_default_install sub_tests.CONFIG = no_default_install
!contains(QT_BUILD_PARTS, tests) { !contains(QT_BUILD_PARTS, tests) {

View File

@ -9,30 +9,9 @@
# We mean it. # We mean it.
# #
TEMPLATE = app load(qt_app)
load(qt_build_paths)
DESTDIR = $$MODULE_BASE_OUTDIR/bin
CONFIG += console 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 # If we are doing a prefix build, create a "module" pri which enables
# qtPrepareTool() to work with the non-installed build. # qtPrepareTool() to work with the non-installed build.

View File

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

View File

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

View File

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

View File

@ -9,6 +9,8 @@
#ifndef LIBGLESV2_MATHUTIL_H_ #ifndef LIBGLESV2_MATHUTIL_H_
#define LIBGLESV2_MATHUTIL_H_ #define LIBGLESV2_MATHUTIL_H_
#include <intrin.h>
#include "common/system.h" #include "common/system.h"
#include "common/debug.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/VertexBuffer.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/VertexDataManager.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 { angle_d3d11 {
HEADERS += \ HEADERS += \

View File

@ -38,6 +38,10 @@ foreach(module ${CMAKE_MODULES_UNDER_TEST})
) )
endforeach() 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) macro(expect_pass _dir)
string(REPLACE "(" "_" testname "${_dir}") string(REPLACE "(" "_" testname "${_dir}")
string(REPLACE ")" "_" testname "${testname}") string(REPLACE ")" "_" testname "${testname}")

View File

@ -79,7 +79,7 @@ class QFlags
{ {
Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)), Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)),
"QFlags uses an int as storage, so an enum with underlying " "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; struct Private;
typedef int (Private::*Zero); typedef int (Private::*Zero);
public: public:

View File

@ -138,6 +138,10 @@ public:
Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier) Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)
//shorter names for shortcuts //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 { enum Modifier {
META = Qt::MetaModifier, META = Qt::MetaModifier,
SHIFT = Qt::ShiftModifier, 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 Reads the '\\0'-terminated string \a s from the stream and returns
a reference to the stream. a reference to the stream.
Space for the string is allocated using \c new -- the caller must The string is deserialized using \c{readBytes()}.
destroy it with \c{delete[]}.
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) 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 Reads the buffer \a s from the stream and returns a reference to
the stream. the stream.
The buffer \a s is allocated using \c new. Destroy it with the \c The buffer \a s is allocated using \c{new []}. Destroy it with the
delete[] operator. \c{delete []} operator.
The \a l parameter is set to the length of the buffer. If the 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 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 Writes the '\\0'-terminated string \a s to the stream and returns a
reference to the stream. 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) 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 QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const
{ {
Q_ASSERT(fileEngine); // should never be called when using the native FS Q_ASSERT(fileEngine); // should never be called when using the native FS
if (fileTimes.size() != 3)
fileTimes.resize(3);
if (!cache_enabled) if (!cache_enabled)
clearFlags(); clearFlags();
uint cf; uint cf;

View File

@ -58,6 +58,7 @@
#include "qatomic.h" #include "qatomic.h"
#include "qshareddata.h" #include "qshareddata.h"
#include "qfilesystemengine_p.h" #include "qfilesystemengine_p.h"
#include "qvector.h"
#include <QtCore/private/qabstractfileengine_p.h> #include <QtCore/private/qabstractfileengine_p.h>
#include <QtCore/private/qfilesystementry_p.h> #include <QtCore/private/qfilesystementry_p.h>
@ -152,7 +153,12 @@ public:
bool cache_enabled : 1; bool cache_enabled : 1;
mutable uint fileFlags; mutable uint fileFlags;
mutable qint64 fileSize; 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 inline bool getCachedFlag(uint c) const
{ return cache_enabled ? (cachedFlags & c) : 0; } { return cache_enabled ? (cachedFlags & c) : 0; }
inline void setCachedFlag(uint c) const 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 The environment of the calling process can be obtained using
QProcessEnvironment::systemEnvironment(). QProcessEnvironment::systemEnvironment().
On Unix systems, the variable names are case-sensitive. For that reason, On Unix systems, the variable names are case-sensitive. Note that the
this class will not touch the names of the variables. Note as well that
Unix environment allows both variable names and contents to contain arbitrary Unix environment allows both variable names and contents to contain arbitrary
binary data (except for the NUL character), but this is not supported by binary data (except for the NUL character). QProcessEnvironment will preserve
QProcessEnvironment. This class only supports names and values that are such variables, but does not support manipulating variables whose names or
encodable by the current locale settings (see QTextCodec::codecForLocale). values are not encodable by the current locale settings (see
QTextCodec::codecForLocale).
On Windows, the variable names are case-insensitive. Therefore, On Windows, the variable names are case-insensitive, but case-preserving.
QProcessEnvironment will always uppercase the names and do case-insensitive QProcessEnvironment behaves accordingly.
comparisons.
On Windows CE, the concept of environment does not exist. This class will 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 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 Returns true if the environment variable of name \a name is found in
this QProcessEnvironment object. 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() \sa insert(), value()
*/ */
@ -314,10 +310,6 @@ bool QProcessEnvironment::contains(const QString &name) const
into this QProcessEnvironment object. If that variable already existed, into this QProcessEnvironment object. If that variable already existed,
it is replaced by the new value. 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 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. 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 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, QProcessEnvironment object. If that variable did not exist before,
nothing happens. 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() \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, \a name and returns its value. If the variable is not found in this object,
then \a defaultValue is returned instead. 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() \sa contains(), insert(), remove()
*/ */
QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const 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 each environment variable that is set. The environment variable's name
and its value are separated by an equal character ('='). and its value are separated by an equal character ('=').
The QStringList contents returned by this function are suitable for use The QStringList contents returned by this function are suitable for
with the QProcess::setEnvironment function. However, it is recommended presentation.
to use QProcess::setProcessEnvironment instead since that will avoid Use with the QProcess::setEnvironment function is not recommended due to
unnecessary copying of the data. potential encoding problems under Unix, and worse performance.
\sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(), \sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(),
QProcess::setEnvironment() QProcess::setEnvironment()

View File

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

View File

@ -53,10 +53,10 @@
// We mean it. // We mean it.
// //
QT_BEGIN_NAMESPACE
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
/* /*
Locks 2 mutexes in a defined order, avoiding a recursive lock if Locks 2 mutexes in a defined order, avoiding a recursive lock if
we're trying to lock the same mutex twice. 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 Releases the \a lockedMutex and waits on the wait condition. The
\a lockedMutex must be initially locked by the calling thread. If \a \a lockedMutex must be initially locked by the calling thread. If \a
lockedMutex is not in a locked state, this function returns lockedMutex is not in a locked state, the behavior is undefined. If
immediately. If \a lockedMutex is a recursive mutex, this function \a lockedMutex is a recursive mutex, this function
returns immediately. The \a lockedMutex will be unlocked, and the returns immediately. The \a lockedMutex will be unlocked, and the
calling thread will block until either of these conditions is met: calling thread will block until either of these conditions is met:

View File

@ -262,6 +262,10 @@ public:
private: private:
friend class QDateTimePrivate; friend class QDateTimePrivate;
void detach(); 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; QExplicitlySharedDataPointer<QDateTimePrivate> d;
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM

View File

@ -284,51 +284,51 @@ QLocaleId QLocaleId::withLikelySubtagsRemoved() const
return max; return max;
} }
QString QLocaleId::bcp47Name() const QByteArray QLocaleId::name(char separator) const
{ {
if (language_id == QLocale::AnyLanguage) if (language_id == QLocale::AnyLanguage)
return QString(); return QByteArray();
if (language_id == QLocale::C) 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 = 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 = 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); char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0);
QString name(len, Qt::Uninitialized); QByteArray name(len, Qt::Uninitialized);
QChar *uc = name.data(); char *uc = name.data();
*uc++ = ushort(lang[0]); *uc++ = lang[0];
*uc++ = ushort(lang[1]); *uc++ = lang[1];
if (lang[2] != 0) if (lang[2] != 0)
*uc++ = ushort(lang[2]); *uc++ = lang[2];
if (script) { if (script) {
*uc++ = QLatin1Char('-'); *uc++ = separator;
*uc++ = ushort(script[0]); *uc++ = script[0];
*uc++ = ushort(script[1]); *uc++ = script[1];
*uc++ = ushort(script[2]); *uc++ = script[2];
*uc++ = ushort(script[3]); *uc++ = script[3];
} }
if (country) { if (country) {
*uc++ = QLatin1Char('-'); *uc++ = separator;
*uc++ = ushort(country[0]); *uc++ = country[0];
*uc++ = ushort(country[1]); *uc++ = country[1];
if (country[2] != 0) if (country[2] != 0)
*uc++ = ushort(country[2]); *uc++ = country[2];
} }
return name; return name;
} }
QString QLocalePrivate::bcp47Name() const QByteArray QLocalePrivate::bcp47Name(char separator) const
{ {
if (m_data->m_language_id == QLocale::AnyLanguage) if (m_data->m_language_id == QLocale::AnyLanguage)
return QString(); return QByteArray();
if (m_data->m_language_id == QLocale::C) 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); 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) 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 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 #ifdef QT_USE_ICU
bool ok = true; bool ok = true;
QString result = QIcu::toUpper(d->m_localeID, str, &ok); QString result = QIcu::toUpper(d->bcp47Name('_'), str, &ok);
if (ok) if (ok)
return result; return result;
// else fall through and use Qt's toUpper // else fall through and use Qt's toUpper
@ -2511,7 +2511,7 @@ QString QLocale::toLower(const QString &str) const
{ {
#ifdef QT_USE_ICU #ifdef QT_USE_ICU
bool ok = true; bool ok = true;
QString result = QIcu::toLower(d->m_localeID, str, &ok); const QString result = QIcu::toLower(d->bcp47Name('_'), str, &ok);
if (ok) if (ok)
return result; return result;
// else fall through and use Qt's toUpper // else fall through and use Qt's toUpper
@ -3662,14 +3662,14 @@ QStringList QLocale::uiLanguages() const
const QLocaleId min = max.withLikelySubtagsRemoved(); const QLocaleId min = max.withLikelySubtagsRemoved();
QStringList uiLanguages; QStringList uiLanguages;
uiLanguages.append(min.bcp47Name()); uiLanguages.append(QString::fromLatin1(min.name()));
if (id.script_id) { if (id.script_id) {
id.script_id = 0; id.script_id = 0;
if (id != min && id.withLikelySubtagsAdded() == max) if (id != min && id.withLikelySubtagsAdded() == max)
uiLanguages.append(id.bcp47Name()); uiLanguages.append(QString::fromLatin1(id.name()));
} }
if (max != min && max != id) if (max != min && max != id)
uiLanguages.append(max.bcp47Name()); uiLanguages.append(QString::fromLatin1(max.name()));
return uiLanguages; return uiLanguages;
} }

View File

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

View File

@ -1,7 +1,7 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
# Name of the project which must match the outputdir. Determines the .index file # 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. # Directories in which to search for files to document and images.
# By default set to the root directory of the project for sources # 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 # Defines the name of the project. You cannot use operators (+, =, -) in
# the name. Properties for this project are set using a qhp.<projectname>.property # the name. Properties for this project are set using a qhp.<projectname>.property
# format. # format.
qhp.projects = qtdbus qhp.projects = QtDBus
# Sets the name of the output qhp file. # 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 # Namespace for the output file. This namespace is used to distinguish between
# different documentation files in Creator/Assistant. # 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 # Title for the package, will be the main title for the package in
# Assistant/Creator. # 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. # Only update the name of the project for the next variables.
qhp.qtdbus.virtualFolder = qtdbus qhp.QtDBus.virtualFolder = qtdbus
qhp.qtdbus.subprojects = classes qhp.QtDBus.subprojects = classes
qhp.qtdbus.subprojects.classes.title = C++ Classes qhp.QtDBus.subprojects.classes.title = C++ Classes
qhp.qtdbus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes
qhp.qtdbus.subprojects.classes.selectors = class fake:headerfile qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile
qhp.qtdbus.subprojects.classes.sortPages = true 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) !!IF !isEmpty(CMAKE_GL_INCDIRS)
@ -17,4 +60,67 @@ unset(_qt5gui_OPENGL_INCLUDE_DIR CACHE)
!!ENDIF !!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 !!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. // We need to inherit QObject to expose the enums to QML.
class Q_GUI_EXPORT QAccessible class Q_GUI_EXPORT QAccessible
#ifndef Q_QDOC
:public QObject
#endif
{ {
Q_OBJECT Q_GADGET
Q_ENUMS(Role Event State) Q_ENUMS(Role Event State)
public: public:

View File

@ -37,18 +37,49 @@ QMAKE_LIBS += $$QMAKE_LIBS_GUI
load(cmake_functions) 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) { 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_GL_HEADER_NAME = GLES/gl.h
CMAKE_QT_OPENGL_IMPLEMENTATION = GLES
} else:contains(QT_CONFIG, opengles2) { } 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_GL_HEADER_NAME = GLES2/gl2.h
CMAKE_QT_OPENGL_IMPLEMENTATION = GLESv2
} else { } 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 CMAKE_GL_HEADER_NAME = GL/gl.h
mac: CMAKE_GL_HEADER_NAME = 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 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 #ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
QFactoryLoader *qt_iconEngineFactoryLoader()
{
return loader();
}
#endif #endif

View File

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

View File

@ -966,7 +966,7 @@ QKeyEvent::~QKeyEvent()
\sa QApplication::keyboardModifiers() \sa QApplication::keyboardModifiers()
*/ */
//###### We must check with XGetModifierMapping
Qt::KeyboardModifiers QKeyEvent::modifiers() const Qt::KeyboardModifiers QKeyEvent::modifiers() const
{ {
if (key() == Qt::Key_Shift) if (key() == Qt::Key_Shift)
@ -977,6 +977,8 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::AltModifier); return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::AltModifier);
if (key() == Qt::Key_Meta) if (key() == Qt::Key_Meta)
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::MetaModifier); return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::MetaModifier);
if (key() == Qt::Key_AltGr)
return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::GroupSwitchModifier);
return QInputEvent::modifiers(); return QInputEvent::modifiers();
} }
@ -990,10 +992,10 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const
*/ */
bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) 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(); const uint platform = QKeySequencePrivate::currentKeyPlatforms();
uint N = QKeySequencePrivate::numberOfKeyBindings; uint N = QKeySequencePrivate::numberOfKeyBindings;
int first = 0; int first = 0;
int last = N - 1; int last = N - 1;

View File

@ -1640,6 +1640,10 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
} }
emit qApp->focusWindowChanged(newFocus); emit qApp->focusWindowChanged(newFocus);
if (previous)
emit previous->activeChanged();
if (newFocus)
emit newFocus->activeChanged();
} }
void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse) void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
@ -1736,6 +1740,9 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
QCloseEvent event; QCloseEvent event;
QGuiApplication::sendSpontaneousEvent(e->window.data(), &event); QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
if (e->accepted) {
*(e->accepted) = !event.isAccepted();
}
} }
void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e) 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+")) *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
<< QModifKeyName(Qt::SHIFT, QLatin1String("shift+")) << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
<< QModifKeyName(Qt::ALT, QLatin1String("alt+")) << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
<< QModifKeyName(Qt::META, QLatin1String("meta+")); << QModifKeyName(Qt::META, QLatin1String("meta+"))
<< QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+"));
} }
} else { } else {
gmodifs = globalPortableModifs(); gmodifs = globalPortableModifs();
@ -1233,7 +1234,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
*gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+")) *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
<< QModifKeyName(Qt::SHIFT, QLatin1String("shift+")) << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
<< QModifKeyName(Qt::ALT, QLatin1String("alt+")) << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
<< QModifKeyName(Qt::META, QLatin1String("meta+")); << QModifKeyName(Qt::META, QLatin1String("meta+"))
<< QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+"));
} }
} }
if (!gmodifs) return ret; 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('+'))) modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
<< QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").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::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 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); addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format);
if ((key & Qt::SHIFT) == Qt::SHIFT) if ((key & Qt::SHIFT) == Qt::SHIFT)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format); 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; QString p;
if (key && key < Qt::Key_Escape && key != Qt::Key_Space) { if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {

View File

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

View File

@ -873,6 +873,14 @@ bool QWindow::isExposed() const
return d->exposed; 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. 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 maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged REVISION 1)
Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged 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 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(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(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged REVISION 1)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1)
@ -170,8 +171,6 @@ public:
void setMask(const QRegion &region); void setMask(const QRegion &region);
QRegion mask() const; QRegion mask() const;
void requestActivate();
bool isActive() const; bool isActive() const;
void reportContentOrientationChange(Qt::ScreenOrientation orientation); void reportContentOrientationChange(Qt::ScreenOrientation orientation);
@ -264,6 +263,8 @@ public:
static QWindow *fromWinId(WId id); static QWindow *fromWinId(WId id);
public Q_SLOTS: public Q_SLOTS:
Q_REVISION(1) void requestActivate();
void setVisible(bool visible); void setVisible(bool visible);
void show(); void show();
@ -310,6 +311,7 @@ Q_SIGNALS:
void visibleChanged(bool arg); void visibleChanged(bool arg);
Q_REVISION(1) void visibilityChanged(QWindow::Visibility visibility); Q_REVISION(1) void visibilityChanged(QWindow::Visibility visibility);
Q_REVISION(1) void activeChanged();
Q_REVISION(1) void contentOrientationChanged(Qt::ScreenOrientation orientation); Q_REVISION(1) void contentOrientationChanged(Qt::ScreenOrientation orientation);
void focusObjectChanged(QObject *object); void focusObjectChanged(QObject *object);

View File

@ -140,11 +140,11 @@ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &new
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
} }
void QWindowSystemInterface::handleCloseEvent(QWindow *tlw) void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
{ {
if (tlw) { if (tlw) {
QWindowSystemInterfacePrivate::CloseEvent *e = QWindowSystemInterfacePrivate::CloseEvent *e =
new QWindowSystemInterfacePrivate::CloseEvent(tlw); new QWindowSystemInterfacePrivate::CloseEvent(tlw, accepted);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); 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 handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleGeometryChange(QWindow *w, const QRect &newRect); 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 handleEnterEvent(QWindow *w, const QPointF &local = QPointF(), const QPointF& global = QPointF());
static void handleLeaveEvent(QWindow *w); static void handleLeaveEvent(QWindow *w);
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF()); 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 { class CloseEvent : public WindowSystemEvent {
public: public:
explicit CloseEvent(QWindow *w) explicit CloseEvent(QWindow *w, bool *a = 0)
: WindowSystemEvent(Close), window(w) { } : WindowSystemEvent(Close), window(w), accepted(a)
{ }
QPointer<QWindow> window; QPointer<QWindow> window;
bool *accepted;
}; };
class GeometryChangeEvent : public WindowSystemEvent { class GeometryChangeEvent : public WindowSystemEvent {

View File

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

View File

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

View File

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

View File

@ -55,7 +55,11 @@ QT_BEGIN_NAMESPACE
static bool ignoreProxyFor(const QNetworkProxyQuery &query) 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) { foreach (const QByteArray &rawToken, noProxyTokens) {
QByteArray token = rawToken.trimmed(); QByteArray token = rawToken.trimmed();

View File

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

View File

@ -934,8 +934,11 @@ void QSslSocketBackendPrivate::transmit()
#ifdef QSSLSOCKET_DEBUG #ifdef QSSLSOCKET_DEBUG
qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect"; qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect";
#endif #endif
plainSocket->disconnectFromHost(); shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
break; 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_SYSCALL: // some IO error
case SSL_ERROR_SSL: // error in the SSL library 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, // 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() void QSslSocketBackendPrivate::disconnectFromHost()
{ {
if (ssl) { if (ssl) {
q_SSL_shutdown(ssl); if (!shutdown) {
transmit(); q_SSL_shutdown(ssl);
shutdown = true;
transmit();
}
} }
plainSocket->disconnectFromHost(); plainSocket->disconnectFromHost();
} }

View File

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

View File

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

View File

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

View File

@ -47,11 +47,17 @@
#include <QtCore/QElapsedTimer> #include <QtCore/QElapsedTimer>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
#include <QtGui/private/qfontengine_ft_p.h> #include <QtGui/private/qfontengine_ft_p.h>
#include <QtGui/private/qfontengine_p.h> #include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qfontengine_qpa_p.h> #include <QtGui/private/qfontengine_qpa_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qguiapplication.h>
#include <ft2build.h> #include <ft2build.h>
#include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_TABLES_H
@ -640,6 +646,19 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
break; 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); engine->setDefaultHintStyle(default_hint_style);
if (antialias) { if (antialias) {

View File

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

View File

@ -70,6 +70,7 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
bool compression = true; bool compression = true;
int jitterLimit = 0; int jitterLimit = 0;
int grab = 0;
QStringList args = specification.split(QLatin1Char(':')); QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) { foreach (const QString &arg, args) {
@ -77,11 +78,14 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
compression = false; compression = false;
else if (arg.startsWith(QLatin1String("dejitter="))) else if (arg.startsWith(QLatin1String("dejitter=")))
jitterLimit = arg.mid(9).toInt(); jitterLimit = arg.mid(9).toInt();
else if (arg.startsWith(QLatin1String("grab=")))
grab = arg.mid(5).toInt();
} }
int fd; int fd;
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (fd >= 0) { if (fd >= 0) {
::ioctl(fd, EVIOCGRAB, grab);
return new QEvdevMouseHandler(device, fd, compression, jitterLimit); return new QEvdevMouseHandler(device, fd, compression, jitterLimit);
} else { } else {
qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno)); 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 #ifndef QT_NO_TREEVIEW
} else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view())) { } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view())) {
header = tv->header(); header = tv->header();
if (header && header->isHidden())
header = 0;
#endif #endif
} }
return header; return header;
@ -766,7 +768,6 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
int column = cell->m_index.column(); int column = cell->m_index.column();
int index = row * view()->model()->columnCount() + column; int index = row * view()->model()->columnCount() + column;
Q_ASSERT(index >= treeView->model()->columnCount());
return index; return index;
} else if (iface->role() == QAccessible::ColumnHeader){ } else if (iface->role() == QAccessible::ColumnHeader){
const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface); 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 bool QAccessibleMenuItem::isValid() const
{ {
return m_action ? true : false; return m_action && m_owner ? true : false;
} }
QAccessibleInterface *QAccessibleMenuItem::parent() const QAccessibleInterface *QAccessibleMenuItem::parent() const

View File

@ -43,6 +43,7 @@
#define QACCESSIBLEMENU_H #define QACCESSIBLEMENU_H
#include <QtWidgets/private/qaccessiblewidget_p.h> #include <QtWidgets/private/qaccessiblewidget_p.h>
#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -120,7 +121,7 @@ protected:
QAction *action() const; QAction *action() const;
private: private:
QAction *m_action; 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 #endif // QT_NO_MENU

View File

@ -1127,7 +1127,7 @@ QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
QAccessibleInterface *QAccessibleMainWindow::child(int index) const QAccessibleInterface *QAccessibleMainWindow::child(int index) const
{ {
QList<QWidget*> kids = childWidgets(mainWindow(), true); QList<QWidget*> kids = childWidgets(mainWindow(), true);
if (index < kids.count()) { if (index >= 0 && index < kids.count()) {
return QAccessible::queryAccessibleInterface(kids.at(index)); return QAccessible::queryAccessibleInterface(kids.at(index));
} }
return 0; 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)) qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
.arg(codec->toUnicode(chars)); .arg(codec->toUnicode(chars));
#endif #endif
const QChar *ch = QString(chars.data()).unicode(); return QString::fromUtf8(chars).at(0).unicode();
return ch->unicode();
} }
quint32 TableGenerator::stringToKeysym(QString keysymName) quint32 TableGenerator::stringToKeysym(QString keysymName)

View File

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

View File

@ -41,6 +41,8 @@ OBJECTIVE_SOURCES += main.mm \
qcocoaintrospection.mm \ qcocoaintrospection.mm \
qcocoakeymapper.mm \ qcocoakeymapper.mm \
SOURCES += messages.cpp
HEADERS += qcocoaintegration.h \ HEADERS += qcocoaintegration.h \
qcocoatheme.h \ qcocoatheme.h \
qcocoabackingstore.h \ qcocoabackingstore.h \
@ -75,6 +77,7 @@ HEADERS += qcocoaintegration.h \
qcocoasystemtrayicon.h \ qcocoasystemtrayicon.h \
qcocoaintrospection.h \ qcocoaintrospection.h \
qcocoakeymapper.h \ qcocoakeymapper.h \
messages.h
RESOURCES += qcocoaresources.qrc 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]; return roleMap[qtRole];
} }
// MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityUnknownRole"; // Treat unknown Qt roles as generic group container items. Returning
return NSAccessibilityUnknownRole; // 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 #endif
const uchar *cursorData = 0; const uchar *cursorData = 0;
const uchar *cursorMaskData = 0; const uchar *cursorMaskData = 0;
QPoint hotspot; QPoint hotspot = cursor->hotSpot();
switch (cursor->shape()) { switch (cursor->shape()) {
case Qt::BitmapCursor: { case Qt::BitmapCursor: {
if (cursor->pixmap().isNull()) if (cursor->pixmap().isNull())
return createCursorFromBitmap(cursor->bitmap(), cursor->mask()); return createCursorFromBitmap(cursor->bitmap(), cursor->mask(), hotspot);
else else
return createCursorFromPixmap(cursor->pixmap()); return createCursorFromPixmap(cursor->pixmap(), hotspot);
break; } break; }
case Qt::BlankCursor: { case Qt::BlankCursor: {
QPixmap pixmap = QPixmap(16, 16); QPixmap pixmap = QPixmap(16, 16);
@ -215,19 +215,19 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
break; } break; }
case Qt::WaitCursor: { case Qt::WaitCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/spincursor.png")); QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/spincursor.png"));
return createCursorFromPixmap(pixmap); return createCursorFromPixmap(pixmap, hotspot);
break; } break; }
case Qt::SizeAllCursor: { case Qt::SizeAllCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png")); QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png"));
return createCursorFromPixmap(pixmap); return createCursorFromPixmap(pixmap, hotspot);
break; } break; }
case Qt::BusyCursor: { case Qt::BusyCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png")); QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png"));
return createCursorFromPixmap(pixmap); return createCursorFromPixmap(pixmap, hotspot);
break; } break; }
case Qt::ForbiddenCursor: { case Qt::ForbiddenCursor: {
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png")); QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png"));
return createCursorFromPixmap(pixmap); return createCursorFromPixmap(pixmap, hotspot);
break; } break; }
#define QT_USE_APPROXIMATE_CURSORS #define QT_USE_APPROXIMATE_CURSORS
#ifdef QT_USE_APPROXIMATE_CURSORS #ifdef QT_USE_APPROXIMATE_CURSORS

View File

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

View File

@ -45,11 +45,34 @@
#include "qcocoaautoreleasepool.h" #include "qcocoaautoreleasepool.h"
#include <QtCore/QtDebug> #include <QtCore/QtDebug>
#include <QtCore/private/qthread_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include "qcocoaapplication.h" #include "qcocoaapplication.h"
#include "qcocoamenuloader.h" #include "qcocoamenuloader.h"
#include "qcocoawindow.h" #include "qcocoawindow.h"
#import "qnsview.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() static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
{ {
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
@ -89,6 +112,7 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
- (void) itemFired:(NSMenuItem*) item - (void) itemFired:(NSMenuItem*) item
{ {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]); QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData);
cocoaItem->activated(); cocoaItem->activated();
} }
@ -101,6 +125,80 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
return cocoaItem->isEnabled(); 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 @end
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -154,6 +252,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem); QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before); QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
menuItem->setParent(this);
cocoaItem->sync(); cocoaItem->sync();
if (beforeItem) { if (beforeItem) {
int index = m_menuItems.indexOf(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"; qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed";
return; return;
} }
if (menuItem->parent() == this)
menuItem->setParent(0);
m_menuItems.removeOne(cocoaItem); m_menuItems.removeOne(cocoaItem);
if (!cocoaItem->isMerged()) { if (!cocoaItem->isMerged()) {
if (m_nativeMenu != [cocoaItem->nsItem() menu]) { if (m_nativeMenu != [cocoaItem->nsItem() menu]) {
@ -266,8 +369,12 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
NSArray *itemArray = [m_nativeMenu itemArray]; NSArray *itemArray = [m_nativeMenu itemArray];
for (unsigned int i = 0; i < [itemArray count]; ++i) { for (unsigned int i = 0; i < [itemArray count]; ++i) {
NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex: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]; [item setHidden:previousIsSeparator];
}
if (![item isHidden]) { if (![item isHidden]) {
previousItem = item; 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. // 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]; [previousItem setHidden:YES];
}
} else { } else {
foreach (QCocoaMenuItem *item, m_menuItems) { foreach (QCocoaMenuItem *item, m_menuItems) {
if (!item->isSeparator()) 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) void QCocoaMenu::setEnabled(bool enabled)
{ {
m_enabled = enabled; m_enabled = enabled;
@ -378,6 +484,11 @@ QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const
return 0; return 0;
} }
QList<QCocoaMenuItem *> QCocoaMenu::items() const
{
return m_menuItems;
}
QList<QCocoaMenuItem *> QCocoaMenu::merged() const QList<QCocoaMenuItem *> QCocoaMenu::merged() const
{ {
QList<QCocoaMenuItem *> result; QList<QCocoaMenuItem *> result;

View File

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

View File

@ -109,6 +109,8 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
[m_nativeMenu addItem: menu->nsMenuItem()]; [m_nativeMenu addItem: menu->nsMenuItem()];
} }
platformMenu->setParent(this);
syncMenu(platformMenu);
[m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()]; [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
} }
@ -123,13 +125,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
} }
m_menus.removeOne(menu); m_menus.removeOne(menu);
if (platformMenu->parent() == this)
platformMenu->setParent(0);
NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()]; NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
[m_nativeMenu removeItemAtIndex: realIndex]; [m_nativeMenu removeItemAtIndex: realIndex];
} }
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) 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) void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)

View File

@ -48,8 +48,16 @@
//#define QT_COCOA_ENABLE_MENU_DEBUG //#define QT_COCOA_ENABLE_MENU_DEBUG
@class NSMenuItem; #ifdef __OBJC__
@class NSMenu; #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 QT_BEGIN_NAMESPACE
@ -96,6 +104,7 @@ private:
NSMenuItem *m_native; NSMenuItem *m_native;
QString m_text; QString m_text;
bool m_textSynced;
QIcon m_icon; QIcon m_icon;
QCocoaMenu *m_menu; QCocoaMenu *m_menu;
bool m_isVisible; bool m_isVisible;

View File

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

View File

@ -41,15 +41,18 @@
#include "qcocoamenuloader.h" #include "qcocoamenuloader.h"
#include "messages.h"
#include "qcocoahelpers.h" #include "qcocoahelpers.h"
#include "qcocoamenubar.h" #include "qcocoamenubar.h"
#include "qcocoamenuitem.h" #include "qcocoamenuitem.h"
#include <QtCore/private/qcore_mac_p.h> #include <QtCore/private/qcore_mac_p.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <QtGui/private/qguiapplication_p.h>
QT_FORWARD_DECLARE_CLASS(QCFString) QT_FORWARD_DECLARE_CLASS(QCFString)
QT_FORWARD_DECLARE_CLASS(QString) QT_FORWARD_DECLARE_CLASS(QString)
@ -57,30 +60,6 @@ QT_FORWARD_DECLARE_CLASS(QString)
QT_BEGIN_NAMESPACE 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). Loads and instantiates the main app menu from the menu nib file(s).
@ -328,6 +307,7 @@ QT_END_NAMESPACE
if ([item tag]) { if ([item tag]) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]); QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData);
cocoaItem->activated(); cocoaItem->activated();
} }
} }

View File

@ -65,6 +65,8 @@ public:
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
Q_INVOKABLE void beep();
static void *cglContextForContext(QOpenGLContext *context); static void *cglContextForContext(QOpenGLContext *context);
static void *nsOpenGLContextForContext(QOpenGLContext* context); static void *nsOpenGLContextForContext(QOpenGLContext* context);
@ -113,6 +115,9 @@ private:
// Embedding NSViews as child QWindows // Embedding NSViews as child QWindows
static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView); 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 // Register if a window should deliver touch events. Enabling
// touch events has implications for delivery of other events, // touch events has implications for delivery of other events,
// for example by causing scrolling event lag. // for example by causing scrolling event lag.

View File

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

View File

@ -106,6 +106,8 @@ public:
void setWindowTitle(const QString &title); void setWindowTitle(const QString &title);
void setWindowFilePath(const QString &filePath); void setWindowFilePath(const QString &filePath);
void setWindowIcon(const QIcon &icon); void setWindowIcon(const QIcon &icon);
void setAlertState(bool enabled);
bool isAlertState() const;
void raise(); void raise();
void lower(); void lower();
bool isExposed() const; bool isExposed() const;
@ -125,10 +127,12 @@ public:
NSView *contentView() const; NSView *contentView() const;
void setContentView(NSView *contentView); void setContentView(NSView *contentView);
void setEmbeddedInForeignView(bool subwindow);
void windowWillMove(); void windowWillMove();
void windowDidMove(); void windowDidMove();
void windowDidResize(); void windowDidResize();
void windowWillClose(); bool windowShouldClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const; bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
NSInteger windowLevel(Qt::WindowFlags flags); NSInteger windowLevel(Qt::WindowFlags flags);
@ -173,7 +177,10 @@ public: // for QNSView
NSView *m_contentView; NSView *m_contentView;
QNSView *m_qtView; QNSView *m_qtView;
NSWindow *m_nsWindow; 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; QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags; Qt::WindowFlags m_windowFlags;
@ -190,6 +197,9 @@ public: // for QNSView
bool m_frameStrutEventsEnabled; bool m_frameStrutEventsEnabled;
bool m_isExposed; bool m_isExposed;
int m_registerTouchCount; int m_registerTouchCount;
static const int NoAlertRequest;
NSInteger m_alertRequest;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

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

View File

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

View File

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

View File

@ -106,9 +106,27 @@
// Hit a child, forward to child accessible interface. // Hit a child, forward to child accessible interface.
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
// FIXME: parent could be wrong
QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ]; QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ];
[accessibleElement autorelease]; [accessibleElement autorelease];
return [accessibleElement accessibilityHitTest:point]; 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 @end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -77,6 +77,9 @@ public:
int effectiveWidth() const; int effectiveWidth() const;
int effectiveHeight() const; int effectiveHeight() const;
bool setMouseGrabEnabled(bool grab) { return grab; }
bool setKeyboardGrabEnabled(bool grab) { return grab; }
WId winId() const { return WId(m_view); }; WId winId() const { return WId(m_view); };
QList<QWindowSystemInterface::TouchPoint> &touchPoints() { return m_touchPoints; } QList<QWindowSystemInterface::TouchPoint> &touchPoints() { return m_touchPoints; }
@ -96,6 +99,9 @@ private:
void raiseOrLower(bool raise); void raiseOrLower(bool raise);
void updateWindowLevel(); void updateWindowLevel();
bool blockedByModal(); 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 QT_END_NAMESPACE

View File

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

View File

@ -721,22 +721,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI
if (varChildID.vt != VT_I4) if (varChildID.vt != VT_I4)
return E_INVALIDARG; return E_INVALIDARG;
QAccessibleInterface *acc = childPointer(accessible, varChildID);
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);
}
if (acc) { if (acc) {
*ppdispChild = QWindowsAccessibility::wrap(acc); *ppdispChild = QWindowsAccessibility::wrap(acc);
return S_OK; return S_OK;
@ -825,7 +810,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT var
QString descr; QString descr;
if (varID.lVal) { if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID); QAccessibleInterface *child = childPointer(accessible, varID);
if (!child) if (!child)
return E_FAIL; return E_FAIL;
descr = child->text(QAccessible::Description); descr = child->text(QAccessible::Description);
@ -850,7 +835,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BST
QString help; QString help;
if (varID.lVal) { if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID); QAccessibleInterface *child = childPointer(accessible, varID);
if (!child) if (!child)
return E_FAIL; return E_FAIL;
help = child->text(QAccessible::Help); help = child->text(QAccessible::Help);
@ -909,7 +894,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BST
QString name; QString name;
if (varID.lVal) { if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID); QAccessibleInterface *child = childPointer(accessible, varID);
if (!child) if (!child)
return E_FAIL; return E_FAIL;
name = child->text(QAccessible::Name); name = child->text(QAccessible::Name);
@ -952,7 +937,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VAR
QAccessible::Role role; QAccessible::Role role;
if (varID.lVal) { if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID); QAccessibleInterface *child = childPointer(accessible, varID);
if (!child) if (!child)
return E_FAIL; return E_FAIL;
role = child->role(); role = child->role();
@ -987,7 +972,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA
QAccessible::State state; QAccessible::State state;
if (varID.lVal) { if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID); QAccessibleInterface *child = childPointer(accessible, varID);
if (!child) if (!child)
return E_FAIL; return E_FAIL;
state = child->state(); state = child->state();

View File

@ -153,13 +153,23 @@ protected:
return 0; return 0;
} }
QAccessibleInterface *childPointer(VARIANT varID) static QAccessibleInterface *childPointer(QAccessibleInterface *parent, VARIANT varID)
{ {
// -1 since windows API always uses 1 for the first child // -1 since windows API always uses 1 for the first child
QAccessibleInterface *iface = accessibleInterface(); Q_ASSERT(parent);
if (iface)
return accessibleInterface()->child(varID.lVal - 1); QAccessibleInterface *acc = 0;
return 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: private:

View File

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

View File

@ -842,9 +842,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::FocusOutEvent: case QtWindows::FocusOutEvent:
handleFocusEvent(et, platformWindow); handleFocusEvent(et, platformWindow);
return true; return true;
case QtWindows::ShowEvent:
platformWindow->handleShown();
return false; // Indicate transient children should be shown by windows (SW_PARENTOPENING)
case QtWindows::HideEvent: case QtWindows::HideEvent:
platformWindow->handleHidden(); platformWindow->handleHidden();
return false;// Indicate transient children should be hidden by windows (SW_PARENTCLOSING) 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; } bool hideFiltersDetails() const { return m_hideFiltersDetails; }
void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; } void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; }
void setDefaultSuffix(const QString &s); void setDefaultSuffix(const QString &s);
inline bool hasDefaultSuffix() const { return m_hasDefaultSuffix; }
inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text); inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text);
// Return the selected files for tracking in OnSelectionChanged(). // Return the selected files for tracking in OnSelectionChanged().
@ -857,6 +858,7 @@ public slots:
protected: protected:
explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data); explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data);
bool init(const CLSID &clsId, const IID &iid); bool init(const CLSID &clsId, const IID &iid);
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; } inline IFileDialog * fileDialog() const { return m_fileDialog; }
static QString itemPath(IShellItem *item); static QString itemPath(IShellItem *item);
static QStringList libraryItemFolders(IShellItem *item); static QStringList libraryItemFolders(IShellItem *item);
@ -873,12 +875,13 @@ private:
DWORD m_cookie; DWORD m_cookie;
QStringList m_nameFilters; QStringList m_nameFilters;
bool m_hideFiltersDetails; bool m_hideFiltersDetails;
bool m_hasDefaultSuffix;
QWindowsFileDialogSharedData m_data; QWindowsFileDialogSharedData m_data;
}; };
QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) : QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) :
m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false), 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) 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())); wchar_t *wSuffix = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(s.utf16()));
m_fileDialog->SetDefaultExtension(wSuffix); m_fileDialog->SetDefaultExtension(wSuffix);
} }
@ -1321,33 +1333,45 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnFileOk(IFileDialog *)
class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase
{ {
Q_OBJECT
public: public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) : explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data);
QWindowsNativeFileDialogBase(data) {}
virtual QStringList selectedFiles() const; virtual QStringList selectedFiles() const;
virtual QStringList dialogResult() const; virtual QStringList dialogResult() const;
private slots:
void slotFilterSelected(const QString &);
}; };
// Append a suffix from the name filter "Foo files (*.foo;*.bar)" // Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
// unless the file name already has one. static inline QString suffixFromFilter(const QString &filter)
static inline QString appendSuffix(const QString &fileName, 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("(*.")); int suffixPos = filter.indexOf(QLatin1String("(*."));
if (suffixPos < 0) if (suffixPos < 0)
return fileName; return QString();
suffixPos += 3; suffixPos += 3;
int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1); int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1);
if (endPos < 0) if (endPos < 0)
endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1); endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1);
if (endPos < 0) if (endPos < 0)
endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1); endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1);
if (endPos < 0) return endPos >= 0 ? filter.mid(suffixPos, endPos - suffixPos) : QString();
return fileName; }
return fileName + QLatin1Char('.') + filter.mid(suffixPos, endPos - suffixPos);
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 QStringList QWindowsNativeSaveFileDialog::dialogResult() const
@ -1355,7 +1379,7 @@ QStringList QWindowsNativeSaveFileDialog::dialogResult() const
QStringList result; QStringList result;
IShellItem *item = 0; IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item) if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
result.push_back(appendSuffix(QWindowsNativeFileDialogBase::itemPath(item), selectedNameFilter())); result.push_back(QWindowsNativeFileDialogBase::itemPath(item));
return result; return result;
} }

View File

@ -839,6 +839,15 @@ QWindowsWindow::~QWindowsWindow()
destroyIcon(); 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() void QWindowsWindow::destroyWindow()
{ {
if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows) if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
@ -942,13 +951,19 @@ void QWindowsWindow::setVisible(bool visible)
if (m_data.hwnd) { if (m_data.hwnd) {
if (visible) { if (visible) {
show_sys(); 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 { } else {
if (hasMouseCapture()) if (hasMouseCapture())
setMouseGrabEnabled(false); setMouseGrabEnabled(false);
hide_sys(); hide_sys();
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); fireExpose(QRegion());
} }
} }
} }
@ -998,6 +1013,24 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
return pos; 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() // partially from QWidgetPrivate::show_sys()
void QWindowsWindow::show_sys() const void QWindowsWindow::show_sys() const
{ {
@ -1012,19 +1045,22 @@ void QWindowsWindow::show_sys() const
sm = SW_SHOWMINIMIZED; sm = SW_SHOWMINIMIZED;
if (!isVisible()) if (!isVisible())
sm = SW_SHOWMINNOACTIVE; sm = SW_SHOWMINNOACTIVE;
} else if (state & Qt::WindowMaximized) { } else {
sm = SW_SHOWMAXIMIZED; updateTransientParent();
// Windows will not behave correctly when we try to maximize a window which does not if (state & Qt::WindowMaximized) {
// have minimize nor maximize buttons in the window frame. Windows would then ignore sm = SW_SHOWMAXIMIZED;
// non-available geometry, and rather maximize the widget to the full screen, minus the // Windows will not behave correctly when we try to maximize a window which does not
// window frame (caption). So, we do a trick here, by adding a maximize button before // have minimize nor maximize buttons in the window frame. Windows would then ignore
// maximizing the widget, and then remove the maximize button afterwards. // non-available geometry, and rather maximize the widget to the full screen, minus the
if (flags & Qt::WindowTitleHint && // window frame (caption). So, we do a trick here, by adding a maximize button before
!(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) { // maximizing the widget, and then remove the maximize button afterwards.
fakedMaximize = TRUE; if (flags & Qt::WindowTitleHint &&
setStyle(style() | WS_MAXIMIZEBOX); !(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) if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool)
sm = SW_SHOWNOACTIVATE; 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() void QWindowsWindow::handleHidden()
{ {
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); fireExpose(QRegion());
} }
void QWindowsWindow::setGeometry(const QRect &rectIn) void QWindowsWindow::setGeometry(const QRect &rectIn)
@ -1267,28 +1298,21 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
if (message == WM_ERASEBKGND) // Backing store - ignored. if (message == WM_ERASEBKGND) // Backing store - ignored.
return true; return true;
PAINTSTRUCT ps; 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); // Observed painting problems with Aero style disabled (QTBUG-7865).
} else { if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered))
BeginPaint(hwnd, &ps); InvalidateRect(hwnd, 0, false);
const QRect updateRect = qrectFromRECT(ps.rcPaint);
if (QWindowsContext::verboseIntegration) BeginPaint(hwnd, &ps);
qDebug() << __FUNCTION__ << this << window() << updateRect;
QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect)); // If the a window is obscured by another window (such as a child window)
if (!QWindowsContext::instance()->asyncExpose()) // we still need to send isExposed=true, for compatibility.
QWindowSystemInterface::flushWindowSystemEvents(); // Our tests depend on it.
EndPaint(hwnd, &ps); fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true);
} if (!QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents();
EndPaint(hwnd, &ps);
return true; 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 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; newStyle |= WS_VISIBLE;
setStyle(newStyle); setStyle(newStyle);
const QRect r = window()->screen()->geometry(); const QRect r = effectiveScreen(window())->geometry();
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE; const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent); const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent); setFlag(SynchronousGeometryChangeEvent);

View File

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

View File

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

View File

@ -80,8 +80,6 @@ class QXcbClipboard;
class QXcbWMSupport; class QXcbWMSupport;
class QXcbNativeInterface; class QXcbNativeInterface;
typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
namespace QXcbAtom { namespace QXcbAtom {
enum Atom { enum Atom {
// window-manager <-> client protocols // window-manager <-> client protocols
@ -301,12 +299,36 @@ private:
XcbPollForQueuedEventFunctionPointer m_xcb_poll_for_queued_event; 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 QAbstractEventDispatcher;
class QXcbConnection : public QObject class QXcbConnection : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0); QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0);
~QXcbConnection(); ~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); } QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
@ -356,8 +378,9 @@ public:
void handleXcbError(xcb_generic_error_t *error); void handleXcbError(xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event); void handleXcbEvent(xcb_generic_event_t *event);
void addWindow(xcb_window_t id, QXcbWindow *window); void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener);
void removeWindow(xcb_window_t id); void removeWindowEventListener(xcb_window_t id);
QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id); QXcbWindow *platformWindowFromId(xcb_window_t id);
xcb_generic_event_t *checkEvent(int type); xcb_generic_event_t *checkEvent(int type);
@ -388,6 +411,13 @@ public:
QXcbWindow *focusWindow() const { return m_focusWindow; } QXcbWindow *focusWindow() const { return m_focusWindow; }
void setFocusWindow(QXcbWindow *); 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: private slots:
void processXcbEvents(); void processXcbEvents();
@ -451,6 +481,7 @@ private:
xcb_connection_t *m_connection; xcb_connection_t *m_connection;
const xcb_setup_t *m_setup; const xcb_setup_t *m_setup;
bool m_canGrabServer;
QList<QXcbScreen *> m_screens; QList<QXcbScreen *> m_screens;
int m_primaryScreen; int m_primaryScreen;
@ -516,6 +547,8 @@ private:
Qt::MouseButtons m_buttons; Qt::MouseButtons m_buttons;
QXcbWindow *m_focusWindow; QXcbWindow *m_focusWindow;
QByteArray m_startupId;
}; };
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) #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. if (desktop_proxy) // *WE* already have one.
return false; return false;
xcb_grab_server(xcb_connection()); connection()->grabServer();
// As per Xdnd4, use XdndProxy // As per Xdnd4, use XdndProxy
xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window()); 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_ATOM_WINDOW, 32, 1, &proxy_id);
} }
xcb_ungrab_server(xcb_connection()); connection()->ungrabServer();
} else { } else {
xdnd_widget = w; xdnd_widget = w;
} }

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