Coverage Report

Created: 2026-05-31 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qplatforminputcontext.cpp
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#include "qplatforminputcontext.h"
6
#include <qguiapplication.h>
7
#include <QRect>
8
#include "private/qkeymapper_p.h"
9
#include "private/qhighdpiscaling_p.h"
10
#include <qpa/qplatforminputcontext_p.h>
11
12
#include <QtGui/qtransform.h>
13
14
QT_BEGIN_NAMESPACE
15
16
/*!
17
    \class QPlatformInputContext
18
    \since 5.0
19
    \internal
20
    \preliminary
21
    \ingroup qpa
22
    \brief The QPlatformInputContext class abstracts the input method dependent data and composing state.
23
24
    An input method is responsible for inputting complex text that cannot
25
    be inputted via simple keymap. It converts a sequence of input
26
    events (typically key events) into a text string through the input
27
    method specific converting process. The class of the processes are
28
    widely ranging from simple finite state machine to complex text
29
    translator that pools a whole paragraph of a text with text
30
    editing capability to perform grammar and semantic analysis.
31
32
    To abstract such different input method specific intermediate
33
    information, Qt offers the QPlatformInputContext as base class. The
34
    concept is well known as 'input context' in the input method
35
    domain. An input context is created for a text widget in response
36
    to a demand. It is ensured that an input context is prepared for
37
    an input method before input to a text widget.
38
39
    QPlatformInputContext provides an interface the actual input methods
40
    can derive from by reimplementing methods.
41
42
    \sa QInputMethod
43
*/
44
45
/*!
46
    \internal
47
 */
48
QPlatformInputContext::QPlatformInputContext()
49
0
    : QObject(*(new QPlatformInputContextPrivate))
50
0
{
51
    // Delay initialization of cached input direction
52
    // until super class has finished constructing.
53
0
    QMetaObject::invokeMethod(this, [this]{
54
0
        m_inputDirection = inputDirection();
55
0
    }, Qt::QueuedConnection);
56
0
}
57
58
/*!
59
    \internal
60
 */
61
QPlatformInputContext::~QPlatformInputContext()
62
0
{
63
0
}
64
65
/*!
66
    Returns input context validity. Deriving implementations should return true.
67
 */
68
bool QPlatformInputContext::isValid() const
69
0
{
70
0
    return false;
71
0
}
72
73
/*!
74
    Returns whether the implementation supports \a capability.
75
    \internal
76
    \since 5.4
77
 */
78
bool QPlatformInputContext::hasCapability(Capability capability) const
79
0
{
80
0
    Q_UNUSED(capability);
81
0
    return true;
82
0
}
83
84
/*!
85
    Method to be called when input method needs to be reset. Called by QInputMethod::reset().
86
    No further QInputMethodEvents should be sent as response.
87
 */
88
void QPlatformInputContext::reset()
89
0
{
90
0
}
91
92
void QPlatformInputContext::commit()
93
0
{
94
0
}
95
96
/*!
97
    Notification on editor updates. Called by QInputMethod::update().
98
 */
99
void QPlatformInputContext::update(Qt::InputMethodQueries)
100
0
{
101
0
}
102
103
/*!
104
    Called when the word currently being composed in the input item is tapped by
105
    the user. Input methods often use this information to offer more word
106
    suggestions to the user.
107
 */
108
void QPlatformInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
109
0
{
110
0
    Q_UNUSED(cursorPosition);
111
    // Default behavior for simple ephemeral input contexts. Some
112
    // complex input contexts should not be reset here.
113
0
    if (action == QInputMethod::Click)
114
0
        reset();
115
0
}
116
117
/*!
118
    This function can be reimplemented to filter input events.
119
    Return true if the event has been consumed. Otherwise, the unfiltered event will
120
    be forwarded to widgets as ordinary way. Although the input events have accept()
121
    and ignore() methods, leave it untouched.
122
*/
123
bool QPlatformInputContext::filterEvent(const QEvent *event)
124
0
{
125
0
    Q_UNUSED(event);
126
0
    return false;
127
0
}
128
129
/*!
130
    This function can be reimplemented to return virtual keyboard rectangle in currently active
131
    window coordinates. Default implementation returns invalid rectangle.
132
 */
133
QRectF QPlatformInputContext::keyboardRect() const
134
0
{
135
0
    return QRectF();
136
0
}
137
138
/*!
139
    Active QPlatformInputContext is responsible for providing keyboardRectangle property to QInputMethod.
140
    In addition of providing the value in keyboardRect function, it also needs to call this emit
141
    function whenever the property changes.
142
 */
143
void QPlatformInputContext::emitKeyboardRectChanged()
144
0
{
145
0
    emit QGuiApplication::inputMethod()->keyboardRectangleChanged();
146
0
}
147
148
/*!
149
    This function can be reimplemented to return true whenever input method is animating
150
    shown or hidden. Default implementation returns \c false.
151
 */
152
bool QPlatformInputContext::isAnimating() const
153
0
{
154
0
    return false;
155
0
}
156
157
/*!
158
    Active QPlatformInputContext is responsible for providing animating property to QInputMethod.
159
    In addition of providing the value in isAnimation function, it also needs to call this emit
160
    function whenever the property changes.
161
 */
162
void QPlatformInputContext::emitAnimatingChanged()
163
0
{
164
0
    emit QGuiApplication::inputMethod()->animatingChanged();
165
0
}
166
167
/*!
168
    Request to show input panel.
169
 */
170
void QPlatformInputContext::showInputPanel()
171
0
{
172
0
}
173
174
/*!
175
    Request to hide input panel.
176
 */
177
void QPlatformInputContext::hideInputPanel()
178
0
{
179
0
}
180
181
/*!
182
    Returns input panel visibility status. Default implementation returns \c false.
183
 */
184
bool QPlatformInputContext::isInputPanelVisible() const
185
0
{
186
0
    return false;
187
0
}
188
189
/*!
190
    Active QPlatformInputContext is responsible for providing visible property to QInputMethod.
191
    In addition of providing the value in isInputPanelVisible function, it also needs to call this emit
192
    function whenever the property changes.
193
 */
194
void QPlatformInputContext::emitInputPanelVisibleChanged()
195
0
{
196
0
    emit QGuiApplication::inputMethod()->visibleChanged();
197
0
}
198
199
QLocale QPlatformInputContext::locale() const
200
0
{
201
0
    return QLocale::system();
202
0
}
203
204
void QPlatformInputContext::emitLocaleChanged()
205
0
{
206
0
    emit QGuiApplication::inputMethod()->localeChanged();
207
208
    // Changing the locale might have updated the input direction
209
0
    emitInputDirectionChanged(inputDirection());
210
0
}
211
212
Qt::LayoutDirection QPlatformInputContext::inputDirection() const
213
0
{
214
0
    return locale().textDirection();
215
0
}
216
217
void QPlatformInputContext::emitInputDirectionChanged(Qt::LayoutDirection newDirection)
218
0
{
219
0
    if (newDirection == m_inputDirection)
220
0
        return;
221
222
0
    emit QGuiApplication::inputMethod()->inputDirectionChanged(newDirection);
223
0
    m_inputDirection = newDirection;
224
0
}
225
226
/*!
227
    This virtual method gets called to notify updated focus to \a object.
228
    \warning Input methods must not call this function directly.
229
 */
230
void QPlatformInputContext::setFocusObject(QObject *object)
231
0
{
232
0
    Q_UNUSED(object);
233
0
}
234
235
/*!
236
    Returns \c true if current focus object supports input method events.
237
 */
238
bool QPlatformInputContext::inputMethodAccepted() const
239
0
{
240
0
    return QPlatformInputContextPrivate::s_inputMethodAccepted;
241
0
}
242
243
bool QPlatformInputContextPrivate::s_inputMethodAccepted = false;
244
245
void QPlatformInputContextPrivate::setInputMethodAccepted(bool accepted)
246
0
{
247
0
    QPlatformInputContextPrivate::s_inputMethodAccepted = accepted;
248
0
}
249
250
/*!
251
   \brief QPlatformInputContext::setSelectionOnFocusObject
252
   \param anchorPos Beginning of selection in currently active window native coordinates
253
   \param cursorPos End of selection in currently active window native coordinates
254
*/
255
void QPlatformInputContext::setSelectionOnFocusObject(const QPointF &nativeAnchorPos, const QPointF &nativeCursorPos)
256
0
{
257
0
    QObject *focus = qApp->focusObject();
258
0
    if (!focus)
259
0
        return;
260
261
0
    QWindow *window = qApp->focusWindow();
262
0
    const QPointF &anchorPos = QHighDpi::fromNativePixels(nativeAnchorPos, window);
263
0
    const QPointF &cursorPos = QHighDpi::fromNativePixels(nativeCursorPos, window);
264
265
0
    QInputMethod *im = QGuiApplication::inputMethod();
266
0
    const QTransform mapToLocal = im->inputItemTransform().inverted();
267
0
    bool success;
268
0
    int anchor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, anchorPos * mapToLocal).toInt(&success);
269
0
    if (success) {
270
0
        int cursor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, cursorPos * mapToLocal).toInt(&success);
271
0
        if (success) {
272
0
            if (anchor == cursor && anchorPos != cursorPos)
273
0
                return;
274
0
            QList<QInputMethodEvent::Attribute> imAttributes;
275
0
            imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant()));
276
0
            QInputMethodEvent event(QString(), imAttributes);
277
0
            QGuiApplication::sendEvent(focus, &event);
278
0
        }
279
0
    }
280
0
}
281
282
/*!
283
   \brief QPlatformInputContext::queryFocusObject
284
285
    Queries the current foucus object with a window position in native pixels.
286
*/
287
QVariant QPlatformInputContext::queryFocusObject(Qt::InputMethodQuery query, QPointF nativePosition)
288
0
{
289
0
    const QPointF position = QHighDpi::fromNativePixels(nativePosition, QGuiApplication::focusWindow());
290
0
    const QInputMethod *im = QGuiApplication::inputMethod();
291
0
    const QTransform mapToLocal = im->inputItemTransform().inverted();
292
0
    return im->queryFocusObject(query, mapToLocal.map(position));
293
0
}
294
295
/*!
296
   \brief QPlatformInputContext::inputItemRectangle
297
298
    Returns the input item rectangle for the currently active window
299
    and input methiod in native window coordinates.
300
*/
301
QRectF QPlatformInputContext::inputItemRectangle()
302
0
{
303
0
    QInputMethod *im = QGuiApplication::inputMethod();
304
0
    const QRectF deviceIndependentRectangle = im->inputItemTransform().mapRect(im->inputItemRectangle());
305
0
    return QHighDpi::toNativePixels(deviceIndependentRectangle, QGuiApplication::focusWindow());
306
0
}
307
308
/*!
309
   \brief QPlatformInputContext::inputItemClipRectangle
310
311
    Returns the input item clip rectangle for the currently active window
312
    and input methiod in native window coordinates.
313
*/
314
QRectF QPlatformInputContext::inputItemClipRectangle()
315
0
{
316
0
    return QHighDpi::toNativePixels(
317
0
        QGuiApplication::inputMethod()->inputItemClipRectangle(), QGuiApplication::focusWindow());
318
0
}
319
320
/*!
321
   \brief QPlatformInputContext::cursorRectangle
322
323
    Returns the cursor rectangle for the currently active window
324
    and input methiod in native window coordinates.
325
*/
326
QRectF QPlatformInputContext::cursorRectangle()
327
0
{
328
0
    return QHighDpi::toNativePixels(
329
0
        QGuiApplication::inputMethod()->cursorRectangle(), QGuiApplication::focusWindow());
330
0
}
331
332
/*!
333
   \brief QPlatformInputContext::anchorRectangle
334
335
    Returns the anchor rectangle for the currently active window
336
    and input methiod in native window coordinates.
337
*/
338
QRectF QPlatformInputContext::anchorRectangle()
339
0
{
340
0
    return QHighDpi::toNativePixels(
341
0
        QGuiApplication::inputMethod()->anchorRectangle(), QGuiApplication::focusWindow());
342
0
}
343
344
/*!
345
   \brief QPlatformInputContext::keyboardRectangle
346
347
    Returns the keyboard rectangle for the currently active window
348
    and input methiod in native window coordinates.
349
*/
350
QRectF QPlatformInputContext::keyboardRectangle()
351
0
{
352
0
    return QHighDpi::toNativePixels(
353
0
        QGuiApplication::inputMethod()->keyboardRectangle(), QGuiApplication::focusWindow());
354
0
}
355
356
QT_END_NAMESPACE
357
358
#include "moc_qplatforminputcontext.cpp"