38void QWaylandQtTextInputMethodPrivate::text_input_method_v1_disable(Resource *resource,
struct ::wl_resource *surface)
40 Q_Q(QWaylandQtTextInputMethod);
41 if (
this->resource == resource) {
42 QWaylandSurface *waylandSurface = QWaylandSurface::fromResource(surface);
43 QWaylandSurface *enabledSurface = enabledSurfaces.take(resource);
45 if (Q_UNLIKELY(enabledSurface != waylandSurface))
46 qCWarning(qLcWaylandCompositorInputMethods) <<
"Disabled surface does not match the one currently enabled";
48 emit q->surfaceEnabled(waylandSurface);
155 : QWaylandCompositorExtensionTemplate(container, *
new QWaylandQtTextInputMethodPrivate(compositor))
157 connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired,
160 connect(qGuiApp->inputMethod(), &QInputMethod::visibleChanged,
this, &QWaylandQtTextInputMethod::sendVisibleChanged);
161 connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged,
this, &
QWaylandQtTextInputMethod::sendKeyboardRectangleChanged);
162 connect(qGuiApp->inputMethod(), &QInputMethod::inputDirectionChanged,
this, &
QWaylandQtTextInputMethod::sendInputDirectionChanged);
188 Q_D(
const QWaylandQtTextInputMethod);
191 return int(d->hints);
192 case Qt::ImCursorRectangle:
193 return d->cursorRectangle;
194 case Qt::ImCursorPosition:
195 return d->cursorPosition;
196 case Qt::ImSurroundingText:
197 return d->surroundingText;
198 case Qt::ImAbsolutePosition:
199 return d->absolutePosition;
200 case Qt::ImCurrentSelection:
201 return d->surroundingText.mid(qMin(d->cursorPosition, d->anchorPosition),
202 qAbs(d->anchorPosition - d->cursorPosition));
203 case Qt::ImAnchorPosition:
204 return d->anchorPosition;
205 case Qt::ImTextAfterCursor:
206 if (argument.isValid())
207 return d->surroundingText.mid(d->cursorPosition, argument.toInt());
208 return d->surroundingText.mid(d->cursorPosition);
209 case Qt::ImTextBeforeCursor:
210 if (argument.isValid())
211 return d->surroundingText.left(d->cursorPosition).right(argument.toInt());
212 return d->surroundingText.left(d->cursorPosition);
213 case Qt::ImPreferredLanguage:
214 return d->preferredLanguage;
241 Q_D(QWaylandQtTextInputMethod);
242 if (d->resource ==
nullptr || d->resource->handle ==
nullptr || d->compositor ==
nullptr)
245 if (d->updatingQueries != 0) {
246 qCWarning(qLcWaylandCompositorInputMethods) <<
"Input method event sent while client is updating. Ignored.";
250 Q_ASSERT(!d->waitingForSync);
252 QString oldSurroundText = d->surroundingText;
253 int oldCursorPosition = d->cursorPosition;
254 int oldAnchorPosition = d->anchorPosition;
255 int oldAbsolutePosition = d->absolutePosition;
256 QRect oldCursorRectangle = d->cursorRectangle;
257 QString oldPreferredLanguage = d->preferredLanguage;
258 Qt::InputMethodHints oldHints = d->hints;
260 uint serial = d->compositor->nextSerial();
261 d->send_start_input_method_event(d->resource->handle, serial, d->surroundingTextOffset);
262 for (
const QInputMethodEvent::Attribute &attribute : event->attributes()) {
263 switch (attribute.type) {
264 case QInputMethodEvent::TextFormat:
266 auto properties = attribute.value.value<QTextFormat>().properties();
267 if (properties.size() != 2 || properties.firstKey() != QTextFormat::FontUnderline || properties.lastKey() != QTextFormat::TextUnderlineStyle) {
268 qCWarning(qLcWaylandCompositorInputMethods()) <<
"Only underline text formats currently supported";
271 d->send_input_method_event_attribute(d->resource->handle,
279 case QInputMethodEvent::Cursor:
280 d->cursorPosition = attribute.start;
281 d->send_input_method_event_attribute(d->resource->handle,
286 attribute.value.typeId() == QMetaType::QColor ? attribute.value.value<QColor>().name() : QString());
288 case QInputMethodEvent::Language:
290 case QInputMethodEvent::Ruby:
291 d->send_input_method_event_attribute(d->resource->handle,
296 attribute.value.toString());
298 case QInputMethodEvent::Selection:
299 d->send_input_method_event_attribute(d->resource->handle,
306 case QInputMethodEvent::MimeData:
307 qCWarning(qLcWaylandCompositorInputMethods())
308 <<
"Ignoring QInputMethodEvent::MimeData";
313 d->waitingForSync =
true;
314 d->send_end_input_method_event(d->resource->handle,
316 event->commitString(),
317 event->preeditString(),
318 event->replacementStart(),
319 event->replacementLength());
321 static const qint64 acknowledgeTimeoutMs = qEnvironmentVariable(
"QT_WAYLAND_QTTEXTINPUTMETHOD_TIMEOUT",
322 QLatin1String(
"1000")).toInt();
325 while (d->waitingForSync) {
326 if (acknowledgeTimeoutMs > 0 && timer.hasExpired(acknowledgeTimeoutMs)) {
327 qCWarning(qLcWaylandCompositorInputMethods)
328 <<
"Timed out waiting for acknowledge_input_method()";
329 d->waitingForSync =
false;
332 d->compositor->processWaylandEvents();
336 QCoreApplication::processEvents();
339 Qt::InputMethodQueries queries;
340 if (d->surroundingText != oldSurroundText)
341 queries |= Qt::ImSurroundingText;
342 if (d->cursorPosition != oldCursorPosition)
343 queries |= Qt::ImCursorPosition;
344 if (d->anchorPosition != oldAnchorPosition)
345 queries |= Qt::ImAnchorPosition;
346 if (d->absolutePosition != oldAbsolutePosition)
347 queries |= Qt::ImAbsolutePosition;
348 if (d->cursorRectangle != oldCursorRectangle)
349 queries |= Qt::ImCursorRectangle;
350 if (d->preferredLanguage != oldPreferredLanguage)
351 queries |= Qt::ImPreferredLanguage;
352 if (d->hints != oldHints)
353 queries |= Qt::ImHints;
355 emit updateInputMethod(queries);
366 Q_D(QWaylandQtTextInputMethod);
368 QWaylandQtTextInputMethodPrivate::Resource *resource = surface !=
nullptr ? d->resourceMap().value(surface->waylandClient()) :
nullptr;
369 if (d->resource == resource && d->focusedSurface == surface)
372 if (d->resource !=
nullptr && d->focusedSurface !=
nullptr) {
373 d->send_leave(d->resource->handle, d->focusedSurface->resource());
374 d->focusDestroyListener.reset();
377 d->resource = resource;
378 d->focusedSurface = surface;
380 if (d->resource !=
nullptr && d->focusedSurface !=
nullptr) {
381 d->surroundingText.clear();
382 d->cursorPosition = 0;
383 d->anchorPosition = 0;
384 d->absolutePosition = 0;
385 d->cursorRectangle = QRect();
386 d->preferredLanguage.clear();
387 d->hints = Qt::InputMethodHints();
388 d->send_enter(d->resource->handle, d->focusedSurface->resource());
389 sendInputDirectionChanged();
391 sendInputDirectionChanged();
392 d->focusDestroyListener.listenForDestruction(surface->resource());
393 if (d->inputPanelVisible && d->enabledSurfaces.values().contains(surface))
394 qGuiApp->inputMethod()->show();