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