summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h49
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm57
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro5
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp2
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.cpp15
-rw-r--r--src/gui/painting/qbrush.cpp14
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp34
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h17
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm5
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm7
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm4
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm2
-rw-r--r--src/plugins/platforms/ios/quiview.mm3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp72
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h2
16 files changed, 231 insertions, 59 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h
new file mode 100644
index 0000000000..6666bc56c5
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h
@@ -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]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm
new file mode 100644
index 0000000000..8abd576259
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm
@@ -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]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro
new file mode 100644
index 0000000000..8f447be514
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro
@@ -0,0 +1,5 @@
+#! [0]
+HEADERS += mycocoaeventfilter.h
+OBJECTIVE_SOURCES += mycocoaeventfilter.mm
+LIBS += -framework AppKit
+#! [0]
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index 886b2d0d27..39bfdd7782 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE
/*!
\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
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.cpp b/src/corelib/kernel/qabstractnativeeventfilter.cpp
index 351657d42c..dcbb92f044 100644
--- a/src/corelib/kernel/qabstractnativeeventfilter.cpp
+++ b/src/corelib/kernel/qabstractnativeeventfilter.cpp
@@ -96,14 +96,25 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter()
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.
- 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
the \a message out, i.e. stop it being handled further, return
true; otherwise return false.
- Example:
+ \b {Linux example}
\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
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index acea5682d1..ebb035a2c1 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -584,7 +584,7 @@ void QBrush::detach(Qt::BrushStyle newStyle)
return;
}
- QScopedPointer<QBrushData> x;
+ QScopedPointer<QBrushData, QBrushDataPointerDeleter> x;
switch(newStyle) {
case Qt::TexturePattern: {
QTexturedBrushData *tbd = new QTexturedBrushData;
@@ -600,28 +600,30 @@ void QBrush::detach(Qt::BrushStyle newStyle)
}
case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern:
- case Qt::ConicalGradientPattern:
- x.reset(new QGradientBrushData);
+ case Qt::ConicalGradientPattern: {
+ QGradientBrushData *gbd = new QGradientBrushData;
switch (d->style) {
case Qt::LinearGradientPattern:
case Qt::RadialGradientPattern:
case Qt::ConicalGradientPattern:
- static_cast<QGradientBrushData *>(x.data())->gradient =
+ gbd->gradient =
static_cast<QGradientBrushData *>(d.data())->gradient;
break;
default:
break;
}
+ x.reset(gbd);
break;
+ }
default:
x.reset(new QBrushData);
break;
}
- x->ref.store(1);
+ x->ref.store(1); // must be first lest the QBrushDataPointerDeleter turns into a no-op
x->style = newStyle;
x->color = d->color;
x->transform = d->transform;
- d.reset(x.take());
+ d.swap(x);
}
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index c7f6dd2740..0eb6fc0847 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -59,8 +59,15 @@ Q_LOGGING_CATEGORY(qLcEvdevKeyMap, "qt.qpa.input.keymap")
// simple builtin US keymap
#include "qevdevkeyboard_defaultmap_p.h"
-QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile)
- : m_device(device), m_fd(fd), m_notify(Q_NULLPTR),
+void QFdContainer::reset() Q_DECL_NOTHROW
+{
+ 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_no_zap(disableZap), m_do_compose(enableCompose),
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();
// 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()));
}
QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
{
unloadKeymap();
-
- if (m_fd >= 0)
- qt_safe_close(m_fd);
}
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
@@ -118,13 +122,12 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
qCDebug(qLcEvdevKey) << "Opening keyboard at" << device;
- int fd;
- fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
- if (fd >= 0) {
- ::ioctl(fd, EVIOCGRAB, grab);
+ QFdContainer fd(qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0));
+ if (fd.get() >= 0) {
+ ::ioctl(fd.get(), EVIOCGRAB, grab);
if (repeatDelay > 0 && repeatRate > 0) {
int kbdrep[2] = { repeatDelay, repeatRate };
- ::ioctl(fd, EVIOCSREP, kbdrep);
+ ::ioctl(fd.get(), EVIOCSREP, kbdrep);
}
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.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()
@@ -153,7 +156,7 @@ void QEvdevKeyboardHandler::readKeycode()
int n = 0;
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) {
qWarning("evdevkeyboard: Got EOF from the input device");
@@ -166,8 +169,7 @@ void QEvdevKeyboardHandler::readKeycode()
if (errno == ENODEV) {
delete m_notify;
m_notify = Q_NULLPTR;
- qt_safe_close(m_fd);
- m_fd = -1;
+ m_fd.reset();
}
return;
}
@@ -478,7 +480,7 @@ void QEvdevKeyboardHandler::unloadKeymap()
//Set locks according to keyboard leds
quint16 ledbits[1];
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");
switchLed(LED_NUML,false);
switchLed(LED_CAPSL, false);
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
index b94323fcbb..1ec4915855 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
@@ -129,12 +129,25 @@ inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composi
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
{
Q_OBJECT
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();
enum KeycodeAction {
@@ -187,7 +200,7 @@ private:
void switchLed(int, bool);
QString m_device;
- int m_fd;
+ QFdContainer m_fd;
QSocketNotifier *m_notify;
// keymap handling
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index bc89f540fc..55eec57270 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -252,6 +252,8 @@ QStringList QConnmanManagerInterface::getServices()
bool QConnmanManagerInterface::requestScan(const QString &type)
{
bool scanned = false;
+ if (technologiesMap.isEmpty())
+ getTechnologies();
Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
if (tech->type() == type) {
tech->scan();
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 628357eb39..ccb11f80f1 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -330,6 +330,11 @@ void QCocoaGLContext::updateSurfaceFormat()
[pixelFormat release];
+ GLint swapInterval = -1;
+ [m_context getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+ if (swapInterval >= 0)
+ m_format.setSwapInterval(swapInterval);
+
// Restore the original context
CGLSetCurrentContext(oldContext);
}
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 6165e480dc..02deab59b5 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -321,7 +321,7 @@ QIOSMenu::QIOSMenu()
: QPlatformMenu()
, m_tag(0)
, m_enabled(true)
- , m_visible(true)
+ , m_visible(false)
, m_text(QString())
, m_menuType(DefaultMenu)
, m_effectiveMenuType(DefaultMenu)
@@ -414,7 +414,7 @@ void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem)
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;
emit aboutToShow();
@@ -441,6 +441,8 @@ void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, c
toggleShowUsingUIPickerView(true);
break;
}
+
+ m_visible = true;
}
void QIOSMenu::dismiss()
@@ -462,6 +464,7 @@ void QIOSMenu::dismiss()
}
m_currentMenu = 0;
+ m_visible = false;
}
void QIOSMenu::toggleShowUsingUIMenuController(bool show)
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index 72eb5e27a0..0478c5b8c8 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -229,6 +229,10 @@
@implementation QIOSViewController
+@synthesize prefersStatusBarHidden;
+@synthesize preferredStatusBarUpdateAnimation;
+@synthesize preferredStatusBarStyle;
+
- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
{
if (self = [self init]) {
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index ae14d87a30..8ff0dfbd5f 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -93,7 +93,7 @@ QIOSWindow::~QIOSWindow()
// 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
// cancellation of all touch events.
- [m_view touchesCancelled:0 withEvent:0];
+ [m_view touchesCancelled:[NSSet set] withEvent:0];
clearAccessibleCache();
m_view->m_qioswindow = 0;
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index e039594406..5c493617b1 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -429,7 +429,8 @@
// We do this by assuming that there are no cases where a
// 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");
m_activeTouches.clear();
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 4c908359f3..a5aff7f11f 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -748,8 +748,7 @@ void QXcbKeyboard::updateKeymap()
// update xkb state object
xkb_state_unref(xkb_state);
xkb_state = new_state;
- if (!connection()->hasXKB())
- updateXKBMods();
+ updateXKBMods();
checkForLatinLayout();
}
@@ -774,32 +773,37 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
}
#endif
+void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state)
+{
+ const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED);
+ const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED);
+ const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED);
+ const quint32 xkbMask = xkbModMask(state);
+
+ const quint32 latched = modsLatched & xkbMask;
+ const quint32 locked = modsLocked & xkbMask;
+ quint32 depressed = modsDepressed & xkbMask;
+ // set modifiers in depressed if they don't appear in any of the final masks
+ depressed |= ~(depressed | latched | locked) & xkbMask;
+
+ const xkb_state_component newState
+ = xkb_state_update_mask(kb_state,
+ depressed,
+ latched,
+ locked,
+ 0,
+ 0,
+ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
+
+ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
+ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
+ }
+}
+
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
{
if (m_config && !connection()->hasXKB()) {
- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
- const quint32 xkbMask = xkbModMask(state);
-
- const quint32 latched = modsLatched & xkbMask;
- const quint32 locked = modsLocked & xkbMask;
- quint32 depressed = modsDepressed & xkbMask;
- // set modifiers in depressed if they don't appear in any of the final masks
- depressed |= ~(depressed | latched | locked) & xkbMask;
-
- const xkb_state_component newState
- = xkb_state_update_mask(xkb_state,
- depressed,
- latched,
- locked,
- 0,
- 0,
- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
-
- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
- }
+ updateXKBStateFromState(xkb_state, state);
}
}
@@ -1463,7 +1467,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress)
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();
QMetaMethod method;
@@ -1482,11 +1495,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
Q_ARG(uint, code),
Q_ARG(uint, state),
Q_ARG(bool, type == QEvent::KeyPress));
- if (retval)
+ if (retval) {
+ xkb_state_unref(kb_state);
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
// 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,
code, sym, state, string, isAutoRepeat);
}
+ xkb_state_unref(kb_state);
}
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 817b57ff5b..dfd2926435 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -104,6 +104,8 @@ protected:
void checkForLatinLayout();
private:
+ void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
+
bool m_config;
xcb_keycode_t m_autorepeat_code;