Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I9cfefaf22b010fca937be77979f5fb50574bb71e
This commit is contained in:
commit
d10e4c193b
@ -0,0 +1,49 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 Samuel Gaist <samuel.gaist@edeltech.ch>
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||||
|
** contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//! [0]
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
|
||||||
|
class MyCocoaEventFilter : public QAbstractNativeEventFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
|
||||||
|
};
|
||||||
|
//! [0]
|
@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 Samuel Gaist <samuel.gaist@edeltech.ch>
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||||
|
** contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//! [0]
|
||||||
|
#include "mycocoaeventfilter.h"
|
||||||
|
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
bool CocoaNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
|
||||||
|
{
|
||||||
|
if (eventType == "mac_generic_NSEvent") {
|
||||||
|
NSEvent *event = static_cast<NSEvent *>(message);
|
||||||
|
if ([event type] == NSKeyDown) {
|
||||||
|
// Handle key event
|
||||||
|
qDebug() << QString::fromNSString([event characters]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//! [0]
|
@ -0,0 +1,5 @@
|
|||||||
|
#! [0]
|
||||||
|
HEADERS += mycocoaeventfilter.h
|
||||||
|
OBJECTIVE_SOURCES += mycocoaeventfilter.mm
|
||||||
|
LIBS += -framework AppKit
|
||||||
|
#! [0]
|
@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
/*!
|
/*!
|
||||||
\property QAbstractProxyModel::sourceModel
|
\property QAbstractProxyModel::sourceModel
|
||||||
|
|
||||||
\brief the source model this proxy model.
|
\brief the source model of this proxy model.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//detects the deletion of the source model
|
//detects the deletion of the source model
|
||||||
|
@ -96,14 +96,25 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter()
|
|||||||
In both cases, the \a message can be casted to a MSG pointer.
|
In both cases, the \a message can be casted to a MSG pointer.
|
||||||
The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
|
The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
|
||||||
|
|
||||||
On Mac, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an EventRef.
|
On macOS, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an NSEvent pointer.
|
||||||
|
|
||||||
In your reimplementation of this function, if you want to filter
|
In your reimplementation of this function, if you want to filter
|
||||||
the \a message out, i.e. stop it being handled further, return
|
the \a message out, i.e. stop it being handled further, return
|
||||||
true; otherwise return false.
|
true; otherwise return false.
|
||||||
|
|
||||||
Example:
|
\b {Linux example}
|
||||||
\snippet code/src_corelib_kernel_qabstractnativeeventfilter.cpp 0
|
\snippet code/src_corelib_kernel_qabstractnativeeventfilter.cpp 0
|
||||||
|
|
||||||
|
\b {macOS example}
|
||||||
|
|
||||||
|
mycocoaeventfilter.h:
|
||||||
|
\snippet code/src_corelib_kernel_qabstractnativeeventfilter.h 0
|
||||||
|
|
||||||
|
mycocoaeventfilter.mm:
|
||||||
|
\snippet code/src_corelib_kernel_qabstractnativeeventfilter.mm 0
|
||||||
|
|
||||||
|
myapp.pro:
|
||||||
|
\snippet code/src_corelib_kernel_qabstractnativeeventfilter.pro 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -585,7 +585,7 @@ void QBrush::detach(Qt::BrushStyle newStyle)
|
|||||||
if (newStyle == d->style && d->ref.load() == 1)
|
if (newStyle == d->style && d->ref.load() == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QScopedPointer<QBrushData> x;
|
QScopedPointer<QBrushData, QBrushDataPointerDeleter> x;
|
||||||
switch(newStyle) {
|
switch(newStyle) {
|
||||||
case Qt::TexturePattern: {
|
case Qt::TexturePattern: {
|
||||||
QTexturedBrushData *tbd = new QTexturedBrushData;
|
QTexturedBrushData *tbd = new QTexturedBrushData;
|
||||||
@ -601,28 +601,30 @@ void QBrush::detach(Qt::BrushStyle newStyle)
|
|||||||
}
|
}
|
||||||
case Qt::LinearGradientPattern:
|
case Qt::LinearGradientPattern:
|
||||||
case Qt::RadialGradientPattern:
|
case Qt::RadialGradientPattern:
|
||||||
case Qt::ConicalGradientPattern:
|
case Qt::ConicalGradientPattern: {
|
||||||
x.reset(new QGradientBrushData);
|
QGradientBrushData *gbd = new QGradientBrushData;
|
||||||
switch (d->style) {
|
switch (d->style) {
|
||||||
case Qt::LinearGradientPattern:
|
case Qt::LinearGradientPattern:
|
||||||
case Qt::RadialGradientPattern:
|
case Qt::RadialGradientPattern:
|
||||||
case Qt::ConicalGradientPattern:
|
case Qt::ConicalGradientPattern:
|
||||||
static_cast<QGradientBrushData *>(x.data())->gradient =
|
gbd->gradient =
|
||||||
static_cast<QGradientBrushData *>(d.data())->gradient;
|
static_cast<QGradientBrushData *>(d.data())->gradient;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
x.reset(gbd);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
x.reset(new QBrushData);
|
x.reset(new QBrushData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
x->ref.store(1);
|
x->ref.store(1); // must be first lest the QBrushDataPointerDeleter turns into a no-op
|
||||||
x->style = newStyle;
|
x->style = newStyle;
|
||||||
x->color = d->color;
|
x->color = d->color;
|
||||||
x->transform = d->transform;
|
x->transform = d->transform;
|
||||||
d.reset(x.take());
|
d.swap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,8 +59,15 @@ Q_LOGGING_CATEGORY(qLcEvdevKeyMap, "qt.qpa.input.keymap")
|
|||||||
// simple builtin US keymap
|
// simple builtin US keymap
|
||||||
#include "qevdevkeyboard_defaultmap_p.h"
|
#include "qevdevkeyboard_defaultmap_p.h"
|
||||||
|
|
||||||
QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile)
|
void QFdContainer::reset() Q_DECL_NOTHROW
|
||||||
: m_device(device), m_fd(fd), m_notify(Q_NULLPTR),
|
{
|
||||||
|
if (m_fd >= 0)
|
||||||
|
qt_safe_close(m_fd);
|
||||||
|
m_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile)
|
||||||
|
: m_device(device), m_fd(fd.release()), m_notify(Q_NULLPTR),
|
||||||
m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
|
m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
|
||||||
m_no_zap(disableZap), m_do_compose(enableCompose),
|
m_no_zap(disableZap), m_do_compose(enableCompose),
|
||||||
m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
|
m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
|
||||||
@ -75,16 +82,13 @@ QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool
|
|||||||
unloadKeymap();
|
unloadKeymap();
|
||||||
|
|
||||||
// socket notifier for events on the keyboard device
|
// socket notifier for events on the keyboard device
|
||||||
m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
|
m_notify = new QSocketNotifier(m_fd.get(), QSocketNotifier::Read, this);
|
||||||
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKeycode()));
|
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKeycode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
|
QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
|
||||||
{
|
{
|
||||||
unloadKeymap();
|
unloadKeymap();
|
||||||
|
|
||||||
if (m_fd >= 0)
|
|
||||||
qt_safe_close(m_fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
|
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
|
||||||
@ -118,13 +122,12 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
|
|||||||
|
|
||||||
qCDebug(qLcEvdevKey) << "Opening keyboard at" << device;
|
qCDebug(qLcEvdevKey) << "Opening keyboard at" << device;
|
||||||
|
|
||||||
int fd;
|
QFdContainer 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.get() >= 0) {
|
||||||
if (fd >= 0) {
|
::ioctl(fd.get(), EVIOCGRAB, grab);
|
||||||
::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.get(), EVIOCSREP, kbdrep);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile);
|
return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile);
|
||||||
@ -144,7 +147,7 @@ void QEvdevKeyboardHandler::switchLed(int led, bool state)
|
|||||||
led_ie.code = led;
|
led_ie.code = led;
|
||||||
led_ie.value = state;
|
led_ie.value = state;
|
||||||
|
|
||||||
qt_safe_write(m_fd, &led_ie, sizeof(led_ie));
|
qt_safe_write(m_fd.get(), &led_ie, sizeof(led_ie));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEvdevKeyboardHandler::readKeycode()
|
void QEvdevKeyboardHandler::readKeycode()
|
||||||
@ -153,7 +156,7 @@ void QEvdevKeyboardHandler::readKeycode()
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
forever {
|
forever {
|
||||||
int result = qt_safe_read(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
|
int result = qt_safe_read(m_fd.get(), reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
qWarning("evdevkeyboard: Got EOF from the input device");
|
qWarning("evdevkeyboard: Got EOF from the input device");
|
||||||
@ -166,8 +169,7 @@ void QEvdevKeyboardHandler::readKeycode()
|
|||||||
if (errno == ENODEV) {
|
if (errno == ENODEV) {
|
||||||
delete m_notify;
|
delete m_notify;
|
||||||
m_notify = Q_NULLPTR;
|
m_notify = Q_NULLPTR;
|
||||||
qt_safe_close(m_fd);
|
m_fd.reset();
|
||||||
m_fd = -1;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -478,7 +480,7 @@ void QEvdevKeyboardHandler::unloadKeymap()
|
|||||||
//Set locks according to keyboard leds
|
//Set locks according to keyboard leds
|
||||||
quint16 ledbits[1];
|
quint16 ledbits[1];
|
||||||
memset(ledbits, 0, sizeof(ledbits));
|
memset(ledbits, 0, sizeof(ledbits));
|
||||||
if (::ioctl(m_fd, EVIOCGLED(sizeof(ledbits)), ledbits) < 0) {
|
if (::ioctl(m_fd.get(), EVIOCGLED(sizeof(ledbits)), ledbits) < 0) {
|
||||||
qWarning("evdevkeyboard: Failed to query led states");
|
qWarning("evdevkeyboard: Failed to query led states");
|
||||||
switchLed(LED_NUML,false);
|
switchLed(LED_NUML,false);
|
||||||
switchLed(LED_CAPSL, false);
|
switchLed(LED_CAPSL, false);
|
||||||
|
@ -129,12 +129,25 @@ inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composi
|
|||||||
return ds << c.first << c.second << c.result;
|
return ds << c.first << c.second << c.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QFdContainer
|
||||||
|
{
|
||||||
|
int m_fd;
|
||||||
|
Q_DISABLE_COPY(QFdContainer);
|
||||||
|
public:
|
||||||
|
explicit QFdContainer(int fd = -1) Q_DECL_NOTHROW : m_fd(fd) {}
|
||||||
|
~QFdContainer() { reset(); }
|
||||||
|
|
||||||
|
int get() const Q_DECL_NOTHROW { return m_fd; }
|
||||||
|
|
||||||
|
int release() Q_DECL_NOTHROW { int result = m_fd; m_fd = -1; return result; }
|
||||||
|
void reset() Q_DECL_NOTHROW;
|
||||||
|
};
|
||||||
|
|
||||||
class QEvdevKeyboardHandler : public QObject
|
class QEvdevKeyboardHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile);
|
QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile);
|
||||||
~QEvdevKeyboardHandler();
|
~QEvdevKeyboardHandler();
|
||||||
|
|
||||||
enum KeycodeAction {
|
enum KeycodeAction {
|
||||||
@ -187,7 +200,7 @@ private:
|
|||||||
void switchLed(int, bool);
|
void switchLed(int, bool);
|
||||||
|
|
||||||
QString m_device;
|
QString m_device;
|
||||||
int m_fd;
|
QFdContainer m_fd;
|
||||||
QSocketNotifier *m_notify;
|
QSocketNotifier *m_notify;
|
||||||
|
|
||||||
// keymap handling
|
// keymap handling
|
||||||
|
@ -252,6 +252,8 @@ QStringList QConnmanManagerInterface::getServices()
|
|||||||
bool QConnmanManagerInterface::requestScan(const QString &type)
|
bool QConnmanManagerInterface::requestScan(const QString &type)
|
||||||
{
|
{
|
||||||
bool scanned = false;
|
bool scanned = false;
|
||||||
|
if (technologiesMap.isEmpty())
|
||||||
|
getTechnologies();
|
||||||
Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
|
Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
|
||||||
if (tech->type() == type) {
|
if (tech->type() == type) {
|
||||||
tech->scan();
|
tech->scan();
|
||||||
|
@ -330,6 +330,11 @@ void QCocoaGLContext::updateSurfaceFormat()
|
|||||||
|
|
||||||
[pixelFormat release];
|
[pixelFormat release];
|
||||||
|
|
||||||
|
GLint swapInterval = -1;
|
||||||
|
[m_context getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||||
|
if (swapInterval >= 0)
|
||||||
|
m_format.setSwapInterval(swapInterval);
|
||||||
|
|
||||||
// Restore the original context
|
// Restore the original context
|
||||||
CGLSetCurrentContext(oldContext);
|
CGLSetCurrentContext(oldContext);
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ QIOSMenu::QIOSMenu()
|
|||||||
: QPlatformMenu()
|
: QPlatformMenu()
|
||||||
, m_tag(0)
|
, m_tag(0)
|
||||||
, m_enabled(true)
|
, m_enabled(true)
|
||||||
, m_visible(true)
|
, m_visible(false)
|
||||||
, m_text(QString())
|
, m_text(QString())
|
||||||
, m_menuType(DefaultMenu)
|
, m_menuType(DefaultMenu)
|
||||||
, m_effectiveMenuType(DefaultMenu)
|
, m_effectiveMenuType(DefaultMenu)
|
||||||
@ -412,7 +412,7 @@ void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem)
|
|||||||
|
|
||||||
void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
|
void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
|
||||||
{
|
{
|
||||||
if (m_currentMenu == this || !m_visible || !m_enabled || !parentWindow)
|
if (m_currentMenu == this || !parentWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
emit aboutToShow();
|
emit aboutToShow();
|
||||||
@ -439,6 +439,8 @@ void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, c
|
|||||||
toggleShowUsingUIPickerView(true);
|
toggleShowUsingUIPickerView(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::dismiss()
|
void QIOSMenu::dismiss()
|
||||||
@ -460,6 +462,7 @@ void QIOSMenu::dismiss()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_currentMenu = 0;
|
m_currentMenu = 0;
|
||||||
|
m_visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::toggleShowUsingUIMenuController(bool show)
|
void QIOSMenu::toggleShowUsingUIMenuController(bool show)
|
||||||
|
@ -228,6 +228,10 @@
|
|||||||
|
|
||||||
@implementation QIOSViewController
|
@implementation QIOSViewController
|
||||||
|
|
||||||
|
@synthesize prefersStatusBarHidden;
|
||||||
|
@synthesize preferredStatusBarUpdateAnimation;
|
||||||
|
@synthesize preferredStatusBarStyle;
|
||||||
|
|
||||||
- (id)initWithQIOSScreen:(QIOSScreen *)screen
|
- (id)initWithQIOSScreen:(QIOSScreen *)screen
|
||||||
{
|
{
|
||||||
if (self = [self init]) {
|
if (self = [self init]) {
|
||||||
|
@ -91,7 +91,7 @@ QIOSWindow::~QIOSWindow()
|
|||||||
// practice this doesn't seem to happen when removing the view from its superview. To ensure that
|
// practice this doesn't seem to happen when removing the view from its superview. To ensure that
|
||||||
// Qt's internal state for touch and mouse handling is kept consistent, we therefor have to force
|
// Qt's internal state for touch and mouse handling is kept consistent, we therefor have to force
|
||||||
// cancellation of all touch events.
|
// cancellation of all touch events.
|
||||||
[m_view touchesCancelled:0 withEvent:0];
|
[m_view touchesCancelled:[NSSet set] withEvent:0];
|
||||||
|
|
||||||
clearAccessibleCache();
|
clearAccessibleCache();
|
||||||
m_view->m_qioswindow = 0;
|
m_view->m_qioswindow = 0;
|
||||||
|
@ -423,7 +423,8 @@
|
|||||||
// We do this by assuming that there are no cases where a
|
// We do this by assuming that there are no cases where a
|
||||||
// sub-set of the active touch events are intentionally cancelled.
|
// sub-set of the active touch events are intentionally cancelled.
|
||||||
|
|
||||||
if (touches && (static_cast<NSInteger>([touches count]) != m_activeTouches.count()))
|
NSInteger count = static_cast<NSInteger>([touches count]);
|
||||||
|
if (count != 0 && count != m_activeTouches.count())
|
||||||
qWarning("Subset of active touches cancelled by UIKit");
|
qWarning("Subset of active touches cancelled by UIKit");
|
||||||
|
|
||||||
m_activeTouches.clear();
|
m_activeTouches.clear();
|
||||||
|
@ -748,7 +748,6 @@ void QXcbKeyboard::updateKeymap()
|
|||||||
// update xkb state object
|
// update xkb state object
|
||||||
xkb_state_unref(xkb_state);
|
xkb_state_unref(xkb_state);
|
||||||
xkb_state = new_state;
|
xkb_state = new_state;
|
||||||
if (!connection()->hasXKB())
|
|
||||||
updateXKBMods();
|
updateXKBMods();
|
||||||
|
|
||||||
checkForLatinLayout();
|
checkForLatinLayout();
|
||||||
@ -774,12 +773,11 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state)
|
||||||
{
|
{
|
||||||
if (m_config && !connection()->hasXKB()) {
|
const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED);
|
||||||
const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
|
const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED);
|
||||||
const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
|
const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED);
|
||||||
const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
|
|
||||||
const quint32 xkbMask = xkbModMask(state);
|
const quint32 xkbMask = xkbModMask(state);
|
||||||
|
|
||||||
const quint32 latched = modsLatched & xkbMask;
|
const quint32 latched = modsLatched & xkbMask;
|
||||||
@ -789,7 +787,7 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
|||||||
depressed |= ~(depressed | latched | locked) & xkbMask;
|
depressed |= ~(depressed | latched | locked) & xkbMask;
|
||||||
|
|
||||||
const xkb_state_component newState
|
const xkb_state_component newState
|
||||||
= xkb_state_update_mask(xkb_state,
|
= xkb_state_update_mask(kb_state,
|
||||||
depressed,
|
depressed,
|
||||||
latched,
|
latched,
|
||||||
locked,
|
locked,
|
||||||
@ -800,6 +798,12 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
|||||||
if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||||
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
||||||
|
{
|
||||||
|
if (m_config && !connection()->hasXKB()) {
|
||||||
|
updateXKBStateFromState(xkb_state, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,7 +1467,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|||||||
if (type == QEvent::KeyPress)
|
if (type == QEvent::KeyPress)
|
||||||
targetWindow->updateNetWmUserTime(time);
|
targetWindow->updateNetWmUserTime(time);
|
||||||
|
|
||||||
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
|
// Have a temporary keyboard state filled in from state
|
||||||
|
// this way we allow for synthetic events to have different state
|
||||||
|
// from the current state i.e. you can have Alt+Ctrl pressed
|
||||||
|
// and receive a synthetic key event that has neither Alt nor Ctrl pressed
|
||||||
|
struct xkb_state *kb_state = xkb_state_new(xkb_keymap);
|
||||||
|
if (!kb_state)
|
||||||
|
return;
|
||||||
|
updateXKBStateFromState(kb_state, state);
|
||||||
|
|
||||||
|
xcb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code);
|
||||||
|
|
||||||
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||||
QMetaMethod method;
|
QMetaMethod method;
|
||||||
@ -1482,11 +1495,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|||||||
Q_ARG(uint, code),
|
Q_ARG(uint, code),
|
||||||
Q_ARG(uint, state),
|
Q_ARG(uint, state),
|
||||||
Q_ARG(bool, type == QEvent::KeyPress));
|
Q_ARG(bool, type == QEvent::KeyPress));
|
||||||
if (retval)
|
if (retval) {
|
||||||
|
xkb_state_unref(kb_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString string = lookupString(xkb_state, code);
|
QString string = lookupString(kb_state, code);
|
||||||
|
|
||||||
// Ιf control modifier is set we should prefer latin character, this is
|
// Ιf control modifier is set we should prefer latin character, this is
|
||||||
// used for standard shortcuts in checks like "key == QKeySequence::Copy",
|
// used for standard shortcuts in checks like "key == QKeySequence::Copy",
|
||||||
@ -1557,6 +1572,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|||||||
QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
|
QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
|
||||||
code, sym, state, string, isAutoRepeat);
|
code, sym, state, string, isAutoRepeat);
|
||||||
}
|
}
|
||||||
|
xkb_state_unref(kb_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
|
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
|
||||||
|
@ -104,6 +104,8 @@ protected:
|
|||||||
void checkForLatinLayout();
|
void checkForLatinLayout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
|
||||||
|
|
||||||
bool m_config;
|
bool m_config;
|
||||||
xcb_keycode_t m_autorepeat_code;
|
xcb_keycode_t m_autorepeat_code;
|
||||||
|
|
||||||
|
@ -459,6 +459,24 @@ void tst_QTextDocument::findMultiple()
|
|||||||
cursor = doc->find(expr, cursor);
|
cursor = doc->find(expr, cursor);
|
||||||
QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar"));
|
QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar"));
|
||||||
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
||||||
|
|
||||||
|
QRegularExpression regularExpression("bar");
|
||||||
|
|
||||||
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
cursor = doc->find(regularExpression, cursor, QTextDocument::FindBackward);
|
||||||
|
QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar"));
|
||||||
|
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
||||||
|
cursor = doc->find(regularExpression, cursor, QTextDocument::FindBackward);
|
||||||
|
QCOMPARE(cursor.selectionStart(), text.indexOf("bar"));
|
||||||
|
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
||||||
|
|
||||||
|
cursor.movePosition(QTextCursor::Start);
|
||||||
|
cursor = doc->find(regularExpression, cursor);
|
||||||
|
QCOMPARE(cursor.selectionStart(), text.indexOf("bar"));
|
||||||
|
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
||||||
|
cursor = doc->find(regularExpression, cursor);
|
||||||
|
QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar"));
|
||||||
|
QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QTextDocument::basicIsModifiedChecks()
|
void tst_QTextDocument::basicIsModifiedChecks()
|
||||||
|
@ -26,14 +26,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QtGui>
|
||||||
#include <QOpenGLWindow>
|
|
||||||
#include <QOpenGLContext>
|
|
||||||
#include <QOpenGLFunctions>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QCommandLineParser>
|
|
||||||
#include <QScreen>
|
|
||||||
|
|
||||||
const char applicationDescription[] = "\n\
|
const char applicationDescription[] = "\n\
|
||||||
This application opens multiple windows and continuously schedules updates for\n\
|
This application opens multiple windows and continuously schedules updates for\n\
|
||||||
@ -62,67 +55,95 @@ class Window : public QOpenGLWindow
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Window(int n) : idx(n) {
|
Window(int index) : windowNumber(index + 1), x(0), framesSwapped(0) {
|
||||||
r = g = b = fps = 0;
|
|
||||||
y = 0;
|
color = QColor::fromHsl((index * 30) % 360, 255, 127).toRgb();
|
||||||
|
|
||||||
resize(200, 200);
|
resize(200, 200);
|
||||||
|
|
||||||
|
setObjectName(QString("Window %1").arg(windowNumber));
|
||||||
|
|
||||||
connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped()));
|
connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped()));
|
||||||
fpsTimer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintGL() {
|
void paintGL() {
|
||||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||||
f->glClearColor(r, g, b, 1);
|
f->glClearColor(color.redF(), color.greenF(), color.blueF(), 1);
|
||||||
f->glClear(GL_COLOR_BUFFER_BIT);
|
f->glClear(GL_COLOR_BUFFER_BIT);
|
||||||
switch (idx % 3) {
|
|
||||||
case 0:
|
|
||||||
r += 0.005f;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
g += 0.005f;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
b += 0.005f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (r > 1)
|
|
||||||
r = 0;
|
|
||||||
if (g > 1)
|
|
||||||
g = 0;
|
|
||||||
if (b > 1)
|
|
||||||
b = 0;
|
|
||||||
|
|
||||||
QPainter p(this);
|
QPainter painter(this);
|
||||||
p.setPen(Qt::white);
|
painter.drawLine(x, 0, x, height());
|
||||||
p.drawText(QPoint(20, y), QString(QLatin1String("Window %1 (%2 FPS)")).arg(idx).arg(fps));
|
x = ++x % width();
|
||||||
y += 1;
|
|
||||||
if (y > height() - 20)
|
|
||||||
y = 20;
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void frameSwapped() {
|
void frameSwapped() {
|
||||||
++framesSwapped;
|
++framesSwapped;
|
||||||
if (fpsTimer.elapsed() > 1000) {
|
update();
|
||||||
fps = qRound(framesSwapped * (1000.0 / fpsTimer.elapsed()));
|
|
||||||
framesSwapped = 0;
|
|
||||||
fpsTimer.restart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void exposeEvent(QExposeEvent *event) {
|
||||||
|
if (!isExposed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QSurfaceFormat format = context()->format();
|
||||||
|
qDebug() << this << format.swapBehavior() << "with Vsync =" << (format.swapInterval() ? "ON" : "OFF");
|
||||||
|
if (format.swapInterval() != requestedFormat().swapInterval())
|
||||||
|
qWarning() << "WARNING: Did not get requested swap interval of" << requestedFormat().swapInterval() << "for" << this;
|
||||||
|
|
||||||
|
QOpenGLWindow::exposeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent *event) {
|
||||||
|
qDebug() << this << event;
|
||||||
|
color.setHsl((color.hue() + 90) % 360, color.saturation(), color.lightness());
|
||||||
|
color = color.toRgb();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int idx;
|
int windowNumber;
|
||||||
GLfloat r, g, b;
|
QColor color;
|
||||||
int y;
|
int x;
|
||||||
|
|
||||||
int framesSwapped;
|
int framesSwapped;
|
||||||
QElapsedTimer fpsTimer;
|
friend void printFps();
|
||||||
int fps;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const qreal kFpsInterval = 500;
|
||||||
|
|
||||||
|
void printFps()
|
||||||
|
{
|
||||||
|
static QElapsedTimer timer;
|
||||||
|
if (!timer.isValid()) {
|
||||||
|
timer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const qreal frameFactor = (kFpsInterval / timer.elapsed()) * (1000.0 / kFpsInterval);
|
||||||
|
|
||||||
|
QDebug output = qDebug().nospace();
|
||||||
|
|
||||||
|
qreal averageFps = 0;
|
||||||
|
const QWindowList windows = QGuiApplication::topLevelWindows();
|
||||||
|
for (int i = 0; i < windows.size(); ++i) {
|
||||||
|
Window *w = qobject_cast<Window*>(windows.at(i));
|
||||||
|
Q_ASSERT(w);
|
||||||
|
|
||||||
|
int fps = qRound(w->framesSwapped * frameFactor);
|
||||||
|
output << (i + 1) << "=" << fps << ", ";
|
||||||
|
|
||||||
|
averageFps += fps;
|
||||||
|
w->framesSwapped = 0;
|
||||||
|
}
|
||||||
|
averageFps = qRound(averageFps / windows.size());
|
||||||
|
qreal msPerFrame = 1000.0 / averageFps;
|
||||||
|
|
||||||
|
output << "avg=" << averageFps << ", ms=" << msPerFrame;
|
||||||
|
|
||||||
|
timer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
@ -144,30 +165,24 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|
||||||
QSurfaceFormat fmt;
|
QSurfaceFormat defaultSurfaceFormat;
|
||||||
if (parser.isSet(noVsyncOption)) {
|
defaultSurfaceFormat.setSwapInterval(parser.isSet(noVsyncOption) ? 0 : 1);
|
||||||
qDebug("swap interval 0 (no throttling)");
|
QSurfaceFormat::setDefaultFormat(defaultSurfaceFormat);
|
||||||
fmt.setSwapInterval(0);
|
|
||||||
} else {
|
|
||||||
qDebug("swap interval 1 (sync to vblank)");
|
|
||||||
}
|
|
||||||
QSurfaceFormat::setDefaultFormat(fmt);
|
|
||||||
|
|
||||||
QRect availableGeometry = app.primaryScreen()->availableGeometry();
|
QRect availableGeometry = app.primaryScreen()->availableGeometry();
|
||||||
|
|
||||||
int numberOfWindows = qMax(parser.value(numWindowsOption).toInt(), 1);
|
int numberOfWindows = qMax(parser.value(numWindowsOption).toInt(), 1);
|
||||||
QList<QWindow *> windows;
|
QList<QWindow *> windows;
|
||||||
for (int i = 0; i < numberOfWindows; ++i) {
|
for (int i = 0; i < numberOfWindows; ++i) {
|
||||||
Window *w = new Window(i + 1);
|
Window *w = new Window(i);
|
||||||
windows << w;
|
windows << w;
|
||||||
|
|
||||||
if (i == 0 && parser.isSet(vsyncOneOption)) {
|
if (i == 0 && parser.isSet(vsyncOneOption)) {
|
||||||
qDebug("swap interval 1 for first window only");
|
QSurfaceFormat vsyncedSurfaceFormat = defaultSurfaceFormat;
|
||||||
QSurfaceFormat vsyncedSurfaceFormat = fmt;
|
|
||||||
vsyncedSurfaceFormat.setSwapInterval(1);
|
vsyncedSurfaceFormat.setSwapInterval(1);
|
||||||
w->setFormat(vsyncedSurfaceFormat);
|
w->setFormat(vsyncedSurfaceFormat);
|
||||||
fmt.setSwapInterval(0);
|
defaultSurfaceFormat.setSwapInterval(0);
|
||||||
QSurfaceFormat::setDefaultFormat(fmt);
|
QSurfaceFormat::setDefaultFormat(defaultSurfaceFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int windowWidth = w->width() + 20;
|
static int windowWidth = w->width() + 20;
|
||||||
@ -182,9 +197,15 @@ int main(int argc, char **argv)
|
|||||||
QPoint position = availableGeometry.topLeft();
|
QPoint position = availableGeometry.topLeft();
|
||||||
position += QPoint(col * windowWidth, row * windowHeight);
|
position += QPoint(col * windowWidth, row * windowHeight);
|
||||||
w->setFramePosition(position);
|
w->setFramePosition(position);
|
||||||
w->show();
|
w->showNormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTimer fpsTimer;
|
||||||
|
fpsTimer.setInterval(kFpsInterval);
|
||||||
|
fpsTimer.setTimerType(Qt::PreciseTimer);
|
||||||
|
QObject::connect(&fpsTimer, &QTimer::timeout, &printFps);
|
||||||
|
fpsTimer.start();
|
||||||
|
|
||||||
int r = app.exec();
|
int r = app.exec();
|
||||||
qDeleteAll(windows);
|
qDeleteAll(windows);
|
||||||
return r;
|
return r;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user