QCompleter: Forward mouse press/release to virtual keyboard
When the list view of a QCompleter is visible, it receives mouse events. A mouse press event outside the completer hid it. If a virtual keyboard was active, it did not receive mouse press/release events in case the completer's list view was active. Add a helper to QGuiApplicationPrivate, that detects a virtual keyboard under a mouse event position, and forwards the event if needed. Adapt QCompleter::eventFilter() to use the helper. If a virtual keyboard one exists and a mouse press event occurs inside it, don't hide the completer and forward the event. Add handling of mouse release events, and also forward them to the virtual keyboard, using the helper. Add logging. Fixes: QTBUG-126752 Pick-to: 6.7 6.5 6.2 Change-Id: I613523a9c83b319810397770c43b2eb4ae01c31a Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 93ce8f13fc8042eac976a3c911af7d7664e8d5dc) Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
parent
9c032ad5fe
commit
38e8899249
@ -108,6 +108,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcPopup, "qt.gui.popup");
|
||||
Q_LOGGING_CATEGORY(lcVirtualKeyboard, "qt.gui.virtualkeyboard");
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
using namespace QtMiscUtils;
|
||||
@ -2109,6 +2110,59 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra
|
||||
return window->nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
bool QGuiApplicationPrivate::isUsingVirtualKeyboard()
|
||||
{
|
||||
static const bool usingVirtualKeyboard = getenv("QT_IM_MODULE") == QByteArray("qtvirtualkeyboard");
|
||||
return usingVirtualKeyboard;
|
||||
}
|
||||
|
||||
// If a virtual keyboard exists, forward mouse event
|
||||
bool QGuiApplicationPrivate::maybeForwardEventToVirtualKeyboard(QEvent *e)
|
||||
{
|
||||
if (!isUsingVirtualKeyboard()) {
|
||||
qCDebug(lcVirtualKeyboard) << "Virtual keyboard not supported.";
|
||||
return false;
|
||||
}
|
||||
|
||||
static QPointer<QWindow> virtualKeyboard;
|
||||
const QEvent::Type type = e->type();
|
||||
Q_ASSERT(type == QEvent::MouseButtonPress || type == QEvent::MouseButtonRelease);
|
||||
const auto me = static_cast<QMouseEvent *>(e);
|
||||
const QPointF posF = me->globalPosition();
|
||||
const QPoint pos = posF.toPoint();
|
||||
|
||||
// Is there a visible virtual keyboard at event position?
|
||||
if (!virtualKeyboard) {
|
||||
if (QWindow *win = QGuiApplication::topLevelAt(pos);
|
||||
win->inherits("QtVirtualKeyboard::InputView")) {
|
||||
virtualKeyboard = win;
|
||||
} else {
|
||||
qCDebug(lcVirtualKeyboard) << "Virtual keyboard supported, but inactive.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(virtualKeyboard);
|
||||
const bool virtualKeyboardUnderMouse = virtualKeyboard->isVisible()
|
||||
&& virtualKeyboard->geometry().contains(pos);
|
||||
|
||||
if (!virtualKeyboardUnderMouse) {
|
||||
qCDebug(lcVirtualKeyboard) << type << "at" << pos << "is outside geometry"
|
||||
<< virtualKeyboard->geometry() << "of" << virtualKeyboard.data();
|
||||
return false;
|
||||
}
|
||||
|
||||
QMouseEvent vkbEvent(type, virtualKeyboard->mapFromGlobal(pos), pos,
|
||||
me->button(), me->buttons(), me->modifiers(),
|
||||
me->pointingDevice());
|
||||
|
||||
QGuiApplication::sendEvent(virtualKeyboard, &vkbEvent);
|
||||
qCDebug(lcVirtualKeyboard) << "Forwarded" << type << "to" << virtualKeyboard.data()
|
||||
<< "at" << pos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
|
||||
{
|
||||
Q_TRACE_PARAM_REPLACE(QWindowSystemInterfacePrivate::WindowSystemEvent *, int);
|
||||
|
@ -40,6 +40,9 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcPopup)
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcVirtualKeyboard)
|
||||
|
||||
class QColorTrcLut;
|
||||
class QPlatformIntegration;
|
||||
class QPlatformTheme;
|
||||
@ -165,6 +168,9 @@ public:
|
||||
|
||||
static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event);
|
||||
|
||||
static bool maybeForwardEventToVirtualKeyboard(QEvent *e);
|
||||
static bool isUsingVirtualKeyboard();
|
||||
|
||||
static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
|
||||
{
|
||||
if (!(alignment & Qt::AlignHorizontal_Mask))
|
||||
|
@ -1463,12 +1463,16 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e)
|
||||
}
|
||||
#endif
|
||||
if (!d->popup->underMouse()) {
|
||||
d->popup->hide();
|
||||
if (!QGuiApplicationPrivate::maybeForwardEventToVirtualKeyboard(e))
|
||||
d->popup->hide();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case QEvent::MouseButtonRelease:
|
||||
QGuiApplicationPrivate::maybeForwardEventToVirtualKeyboard(e);
|
||||
return true;
|
||||
case QEvent::InputMethod:
|
||||
case QEvent::ShortcutOverride:
|
||||
QCoreApplication::sendEvent(d->widget, e);
|
||||
|
Loading…
x
Reference in New Issue
Block a user