Add geometry accessors to QPlatformInputContext

Currently the platform plugins use the public QInputMethod
API when querying geometry. However, QInputMethod returns
geometry in device independent pixels, while the platform
plugins require geometry in native pixels.

Add new API to QPlatformInputContext which returns input
geometry in the native window coordinate system:

    QRectF inputItemRectangle()
    QRectF inputItemClipRectangle()
    QRectF cursorRectangle()
    QRectF anchorRectangle()
    QRectF keyboardRectangle()

These make the relevant QHighDpi calls internally, and
such calls can then be moved out of the platform plugins.

Disambiguate inputItemRectangle() in qandroidinputcontext.cpp
by renaming it to screenInputItemRectangle().

Change-Id: I561745b64fb197d64e3dfddcf0751528bb8d0605
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Morten Johan Sørvig 2021-01-13 13:55:02 +01:00 committed by Morten Sørvig
parent 7c57288460
commit fddc0b34df
3 changed files with 85 additions and 4 deletions

View File

@ -41,6 +41,7 @@
#include <qguiapplication.h>
#include <QRect>
#include "private/qkeymapper_p.h"
#include "private/qhighdpiscaling_p.h"
#include <qpa/qplatforminputcontext_p.h>
#include <QtGui/qtransform.h>
@ -297,4 +298,78 @@ void QPlatformInputContext::setSelectionOnFocusObject(const QPointF &anchorPos,
}
}
/*!
\brief QPlatformInputContext::queryFocusObject
Queries the current foucus object with a window position in native pixels.
*/
QVariant QPlatformInputContext::queryFocusObject(Qt::InputMethodQuery query, QPointF nativePosition)
{
const QPointF position = QHighDpi::fromNativePixels(nativePosition, QGuiApplication::focusWindow());
const QInputMethod *im = QGuiApplication::inputMethod();
const QTransform mapToLocal = im->inputItemTransform().inverted();
return im->queryFocusObject(query, mapToLocal.map(position));
}
/*!
\brief QPlatformInputContext::inputItemRectangle
Returns the input item rectangle for the currently active window
and input methiod in native window coordinates.
*/
QRectF QPlatformInputContext::inputItemRectangle()
{
QInputMethod *im = QGuiApplication::inputMethod();
const QRectF deviceIndependentRectangle = im->inputItemTransform().mapRect(im->inputItemRectangle());
return QHighDpi::toNativePixels(deviceIndependentRectangle, QGuiApplication::focusWindow());
}
/*!
\brief QPlatformInputContext::inputItemClipRectangle
Returns the input item clip rectangle for the currently active window
and input methiod in native window coordinates.
*/
QRectF QPlatformInputContext::inputItemClipRectangle()
{
return QHighDpi::toNativePixels(
QGuiApplication::inputMethod()->inputItemClipRectangle(), QGuiApplication::focusWindow());
}
/*!
\brief QPlatformInputContext::cursorRectangle
Returns the cursor rectangle for the currently active window
and input methiod in native window coordinates.
*/
QRectF QPlatformInputContext::cursorRectangle()
{
return QHighDpi::toNativePixels(
QGuiApplication::inputMethod()->cursorRectangle(), QGuiApplication::focusWindow());
}
/*!
\brief QPlatformInputContext::anchorRectangle
Returns the anchor rectangle for the currently active window
and input methiod in native window coordinates.
*/
QRectF QPlatformInputContext::anchorRectangle()
{
return QHighDpi::toNativePixels(
QGuiApplication::inputMethod()->anchorRectangle(), QGuiApplication::focusWindow());
}
/*!
\brief QPlatformInputContext::keyboardRectangle
Returns the keyboard rectangle for the currently active window
and input methiod in native window coordinates.
*/
QRectF QPlatformInputContext::keyboardRectangle()
{
return QHighDpi::toNativePixels(
QGuiApplication::inputMethod()->keyboardRectangle(), QGuiApplication::focusWindow());
}
QT_END_NAMESPACE

View File

@ -97,6 +97,12 @@ public:
bool inputMethodAccepted() const;
static void setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos);
static QVariant queryFocusObject(Qt::InputMethodQuery query, QPointF position);
static QRectF inputItemRectangle();
static QRectF inputItemClipRectangle();
static QRectF cursorRectangle();
static QRectF anchorRectangle();
static QRectF keyboardRectangle();
private:
friend class QGuiApplication;

View File

@ -405,7 +405,7 @@ static JNINativeMethod methods[] = {
{"updateCursorPosition", "()Z", (void *)updateCursorPosition}
};
static QRect inputItemRectangle()
static QRect screenInputItemRectangle()
{
QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle();
QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect();
@ -786,7 +786,7 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
void QAndroidInputContext::touchDown(int x, int y)
{
if (m_focusObject && inputItemRectangle().contains(x, y)) {
if (m_focusObject && screenInputItemRectangle().contains(x, y)) {
// If the user touch the input rectangle, we can show the cursor handle
m_handleMode = ShowCursor;
// The VK will appear in a moment, stop the timer
@ -820,7 +820,7 @@ void QAndroidInputContext::longPress(int x, int y)
if (noHandles)
return;
if (m_focusObject && inputItemRectangle().contains(x, y)) {
if (m_focusObject && screenInputItemRectangle().contains(x, y)) {
BatchEditLock batchEditLock(this);
focusObjectStopComposing();
@ -928,7 +928,7 @@ void QAndroidInputContext::showInputPanel()
else
m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
QRect rect = inputItemRectangle();
QRect rect = screenInputItemRectangle();
QtAndroidInput::showSoftwareKeyboard(rect.left(), rect.top(), rect.width(), rect.height(),
query->value(Qt::ImHints).toUInt(),
query->value(Qt::ImEnterKeyType).toUInt());