From 41a0be329c3f31345afc61b622e49fc4bc3bce08 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 30 Mar 2016 07:32:51 +0200 Subject: Do not disconnect with nullptr when unplugging screens Task-number: QTBUG-42803 Change-Id: I080ec3f0cc2cb55b43a9b8792f03b002b2e0f982 Reviewed-by: Gunnar Sletta Reviewed-by: Shawn Rutledge --- src/gui/kernel/qopenglcontext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 3c033ea39e..7588c36c9b 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -510,8 +510,10 @@ void QOpenGLContext::setScreen(QScreen *screen) void QOpenGLContextPrivate::_q_screenDestroyed(QObject *object) { Q_Q(QOpenGLContext); - if (object == static_cast(screen)) + if (object == static_cast(screen)) { + screen = 0; q->setScreen(0); + } } /*! -- cgit v1.2.3 From 0bb645b1ccc5a9d57b21cf0b2c4306b8e48c611c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Thu, 26 Nov 2015 10:37:24 +0100 Subject: Add support for ImhAnchorRectangle Adds the following API: * QInputMethod::anchorRectangle() * QPlatformInputContext::setSelectionOnFocusObject() This will be used for determining how to display selection handles. Change-Id: If57e3fd58ff0f1ba7899f7dd62bfa9c006028667 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qinputmethod.cpp | 40 ++++++++++++++++++++++++-------- src/gui/kernel/qinputmethod.h | 3 +++ src/gui/kernel/qplatforminputcontext.cpp | 27 +++++++++++++++++++++ src/gui/kernel/qplatforminputcontext.h | 2 ++ 4 files changed, 62 insertions(+), 10 deletions(-) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp index ca988f2523..b81e166d3a 100644 --- a/src/gui/kernel/qinputmethod.cpp +++ b/src/gui/kernel/qinputmethod.cpp @@ -97,6 +97,7 @@ void QInputMethod::setInputItemTransform(const QTransform &transform) d->inputItemTransform = transform; emit cursorRectangleChanged(); + emit anchorRectangleChanged(); } @@ -126,6 +127,19 @@ void QInputMethod::setInputItemRectangle(const QRectF &rect) d->inputRectangle = rect; } +static QRectF inputMethodQueryRectangle_helper(Qt::InputMethodQuery imquery, const QTransform &xform) +{ + QRectF r; + if (QObject *focusObject = qGuiApp->focusObject()) { + QInputMethodQueryEvent query(imquery); + QGuiApplication::sendEvent(focusObject, &query); + r = query.value(imquery).toRectF(); + if (r.isValid()) + r = xform.mapRect(r); + } + return r; +} + /*! \property QInputMethod::cursorRectangle \brief Input item's cursor rectangle in window coordinates. @@ -136,18 +150,20 @@ void QInputMethod::setInputItemRectangle(const QRectF &rect) QRectF QInputMethod::cursorRectangle() const { Q_D(const QInputMethod); + return inputMethodQueryRectangle_helper(Qt::ImCursorRectangle, d->inputItemTransform); +} - QObject *focusObject = qGuiApp->focusObject(); - if (!focusObject) - return QRectF(); - - QInputMethodQueryEvent query(Qt::ImCursorRectangle); - QGuiApplication::sendEvent(focusObject, &query); - QRectF r = query.value(Qt::ImCursorRectangle).toRectF(); - if (!r.isValid()) - return QRectF(); +/*! + \property QInputMethod::anchorRectangle + \brief Input item's anchor rectangle in window coordinates. - return d->inputItemTransform.mapRect(r); + Anchor rectangle is often used by various text editing controls + like text prediction popups for following the text selection. +*/ +QRectF QInputMethod::anchorRectangle() const +{ + Q_D(const QInputMethod); + return inputMethodQueryRectangle_helper(Qt::ImAnchorRectangle, d->inputItemTransform); } /*! @@ -300,6 +316,10 @@ void QInputMethod::update(Qt::InputMethodQueries queries) if (queries & Qt::ImCursorRectangle) emit cursorRectangleChanged(); + + if (queries & (Qt::ImAnchorRectangle)) + emit anchorRectangleChanged(); + } /*! diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h index 68dc679d14..22e4677eaa 100644 --- a/src/gui/kernel/qinputmethod.h +++ b/src/gui/kernel/qinputmethod.h @@ -55,6 +55,7 @@ class Q_GUI_EXPORT QInputMethod : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QInputMethod) Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) + Q_PROPERTY(QRectF anchorRectangle READ anchorRectangle NOTIFY anchorRectangleChanged) Q_PROPERTY(QRectF keyboardRectangle READ keyboardRectangle NOTIFY keyboardRectangleChanged) Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) Q_PROPERTY(bool animating READ isAnimating NOTIFY animatingChanged) @@ -70,6 +71,7 @@ public: // in window coordinates QRectF cursorRectangle() const; // ### what if we have rotations for the item? + QRectF anchorRectangle() const; // ### ditto // keyboard geometry in window coords QRectF keyboardRectangle() const; @@ -102,6 +104,7 @@ public Q_SLOTS: Q_SIGNALS: void cursorRectangleChanged(); + void anchorRectangleChanged(); void keyboardRectangleChanged(); void visibleChanged(); void animatingChanged(); diff --git a/src/gui/kernel/qplatforminputcontext.cpp b/src/gui/kernel/qplatforminputcontext.cpp index bad6422cb8..3f59116e9a 100644 --- a/src/gui/kernel/qplatforminputcontext.cpp +++ b/src/gui/kernel/qplatforminputcontext.cpp @@ -43,6 +43,8 @@ #include "private/qkeymapper_p.h" #include +#include + QT_BEGIN_NAMESPACE /*! @@ -267,5 +269,30 @@ void QPlatformInputContextPrivate::setInputMethodAccepted(bool accepted) QPlatformInputContextPrivate::s_inputMethodAccepted = accepted; } +/*! + * \brief QPlatformInputContext::setSelectionOnFocusObject + * \param anchorPos Beginning of selection in currently active window coordinates + * \param cursorPos End of selection in currently active window coordinates + */ +void QPlatformInputContext::setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos) +{ + QObject *focus = qApp->focusObject(); + if (!focus) + return; + + QInputMethod *im = QGuiApplication::inputMethod(); + const QTransform mapToLocal = im->inputItemTransform().inverted(); + bool success; + int anchor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, anchorPos * mapToLocal).toInt(&success); + if (success) { + int cursor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, cursorPos * mapToLocal).toInt(&success); + if (success) { + QList imAttributes; + imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant())); + QInputMethodEvent event(QString(), imAttributes); + QGuiApplication::sendEvent(focus, &event); + } + } +} QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatforminputcontext.h b/src/gui/kernel/qplatforminputcontext.h index 24c6178541..7afa6b82f2 100644 --- a/src/gui/kernel/qplatforminputcontext.h +++ b/src/gui/kernel/qplatforminputcontext.h @@ -95,6 +95,8 @@ public: virtual void setFocusObject(QObject *object); bool inputMethodAccepted() const; + static void setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos); + private: friend class QGuiApplication; friend class QGuiApplicationPrivate; -- cgit v1.2.3 From f931e5e72d4617023bbea46cba2c0d61bb1efa4f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 7 Apr 2016 15:07:04 +0200 Subject: add cross-platform tablet->mouse event synth; enable on Android It's urgent to fix the issue that on Android, it became impossible to interact with any widget or MouseArea which handles only mouse events but not tablet events, using the stylus, because stylus events are sent only as QTabletEvents. Before 5.6 (change 01d78ba86a631386a4d47b7c12d2a359da28f517) they were sent as touch events, and mouse events were synthesized from those. Whereas on other platforms, every QTabletEvent is followed by a synthesized QMouseEvent. This fix proceeds in the direction that event synthesis should be done in cross-platform code so that platform plugins don't have to repeat it, following the same pattern as for touch->mouse synthesis. Just as in that case, the application can disable it, and the platform plugin can also report that it's unnecessary for Qt to do the synthesis because the platform already does. So QTBUG-51618 is fixed, but QTBUG-47007 requires us to remove the tablet->mouse synthesis from all platform plugins, because the plugin does not know whether the tablet event was accepted or not, so it does not have enough information to decide whether to synthesize a mouse event. Synthesis has been unconditional until now, which contradicts what the documentation says: the mouse event should be sent only if the tablet event is NOT accepted. We can now gradually make this promise come true. [ChangeLog][QtCore][Tablet support] A synthetic mouse event will no longer be sent after every QTabletEvent, only after those which are not accepted (as documented). Task-number: QTBUG-47007 Task-number: QTBUG-51618 Change-Id: I99404e0c2b39bbca4377be6fd48e0c6b20338466 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qguiapplication.cpp | 8 ++++++++ src/gui/kernel/qwindowsysteminterface.cpp | 6 ++++++ src/gui/kernel/qwindowsysteminterface_p.h | 2 ++ 3 files changed, 16 insertions(+) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index ec1e771b90..2bc5462b43 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2300,9 +2300,17 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt, e->tangentialPressure, e->rotation, e->z, e->modifiers, e->uid, button, e->buttons); + ev.setAccepted(false); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); pointData.state = e->buttons; + if (!ev.isAccepted() && !QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse + && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) { + QWindowSystemInterfacePrivate::MouseEvent fake(window, e->timestamp, e->local, e->global, + e->buttons, e->modifiers, Qt::MouseEventSynthesizedByQt); + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; + processMouseEvent(&fake); + } #else Q_UNUSED(e) #endif diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 5b91f1bc7e..00b8e05f30 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE QElapsedTimer QWindowSystemInterfacePrivate::eventTime; bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false; +bool QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse = true; QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed; QMutex QWindowSystemInterfacePrivate::flushEventMutex; QAtomicInt QWindowSystemInterfacePrivate::eventAccepted; @@ -945,4 +946,9 @@ QWindowSystemInterfacePrivate::WheelEvent::WheelEvent(QWindow *w, ulong time, co { } +void QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(bool v) +{ + platformSynthesizesMouse = v; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 3ccf815c54..b218c1c68c 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -352,6 +352,7 @@ public: int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + static void setPlatformSynthesizesMouse(bool v); TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global, int device, int pointerType, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure, @@ -372,6 +373,7 @@ public: qreal rotation; int z; qint64 uid; + static bool platformSynthesizesMouse; }; class TabletEnterProximityEvent : public InputEvent { -- cgit v1.2.3