35void QWaylandQtTextInputMethodPrivate::text_input_method_v1_disable(Resource *resource,
struct ::wl_resource *surface)
37 Q_Q(QWaylandQtTextInputMethod);
38 if (
this->resource == resource) {
39 QWaylandSurface *waylandSurface = QWaylandSurface::fromResource(surface);
40 QWaylandSurface *enabledSurface = enabledSurfaces.take(resource);
42 if (Q_UNLIKELY(enabledSurface != waylandSurface))
43 qCWarning(qLcWaylandCompositorInputMethods) <<
"Disabled surface does not match the one currently enabled";
45 emit q->surfaceEnabled(waylandSurface);
152 : QWaylandCompositorExtensionTemplate(container, *
new QWaylandQtTextInputMethodPrivate(compositor))
154 connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired,
155 this, &QWaylandQtTextInputMethod::focusSurfaceDestroyed);
157 connect(qGuiApp->inputMethod(), &QInputMethod::visibleChanged,
this, &QWaylandQtTextInputMethod::sendVisibleChanged);
158 connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged,
this, &QWaylandQtTextInputMethod::sendKeyboardRectangleChanged);
159 connect(qGuiApp->inputMethod(), &QInputMethod::inputDirectionChanged,
this, &QWaylandQtTextInputMethod::sendInputDirectionChanged);
160 connect(qGuiApp->inputMethod(), &QInputMethod::localeChanged,
this, &QWaylandQtTextInputMethod::sendLocaleChanged);
185 Q_D(
const QWaylandQtTextInputMethod);
188 return int(d->hints);
189 case Qt::ImCursorRectangle:
190 return d->cursorRectangle;
191 case Qt::ImCursorPosition:
192 return d->cursorPosition;
193 case Qt::ImSurroundingText:
194 return d->surroundingText;
195 case Qt::ImAbsolutePosition:
196 return d->absolutePosition;
197 case Qt::ImCurrentSelection:
198 return d->surroundingText.mid(qMin(d->cursorPosition, d->anchorPosition),
199 qAbs(d->anchorPosition - d->cursorPosition));
200 case Qt::ImAnchorPosition:
201 return d->anchorPosition;
202 case Qt::ImTextAfterCursor:
203 if (argument.isValid())
204 return d->surroundingText.mid(d->cursorPosition, argument.toInt());
205 return d->surroundingText.mid(d->cursorPosition);
206 case Qt::ImTextBeforeCursor:
207 if (argument.isValid())
208 return d->surroundingText.left(d->cursorPosition).right(argument.toInt());
209 return d->surroundingText.left(d->cursorPosition);
210 case Qt::ImPreferredLanguage:
211 return d->preferredLanguage;
238 Q_D(QWaylandQtTextInputMethod);
239 if (d->resource ==
nullptr || d->resource->handle ==
nullptr || d->compositor ==
nullptr)
242 if (d->updatingQueries != 0) {
243 qCWarning(qLcWaylandCompositorInputMethods) <<
"Input method event sent while client is updating. Ignored.";
247 Q_ASSERT(!d->waitingForSync);
249 QString oldSurroundText = d->surroundingText;
250 int oldCursorPosition = d->cursorPosition;
251 int oldAnchorPosition = d->anchorPosition;
252 int oldAbsolutePosition = d->absolutePosition;
253 QRect oldCursorRectangle = d->cursorRectangle;
254 QString oldPreferredLanguage = d->preferredLanguage;
255 Qt::InputMethodHints oldHints = d->hints;
257 uint serial = d->compositor->nextSerial();
258 d->send_start_input_method_event(d->resource->handle, serial, d->surroundingTextOffset);
259 for (
const QInputMethodEvent::Attribute &attribute : event->attributes()) {
260 switch (attribute.type) {
261 case QInputMethodEvent::TextFormat:
263 auto properties = attribute.value.value<QTextFormat>().properties();
264 if (properties.size() != 2 || properties.firstKey() != QTextFormat::FontUnderline || properties.lastKey() != QTextFormat::TextUnderlineStyle) {
265 qCWarning(qLcWaylandCompositorInputMethods()) <<
"Only underline text formats currently supported";
268 d->send_input_method_event_attribute(d->resource->handle,
276 case QInputMethodEvent::Cursor:
277 d->cursorPosition = attribute.start;
278 d->send_input_method_event_attribute(d->resource->handle,
283 attribute.value.typeId() == QMetaType::QColor ? attribute.value.value<QColor>().name() : QString());
285 case QInputMethodEvent::Language:
287 case QInputMethodEvent::Ruby:
288 d->send_input_method_event_attribute(d->resource->handle,
293 attribute.value.toString());
295 case QInputMethodEvent::Selection:
296 d->send_input_method_event_attribute(d->resource->handle,
303 case QInputMethodEvent::MimeData:
304 qCWarning(qLcWaylandCompositorInputMethods())
305 <<
"Ignoring QInputMethodEvent::MimeData";
310 d->waitingForSync =
true;
311 d->send_end_input_method_event(d->resource->handle,
313 event->commitString(),
314 event->preeditString(),
315 event->replacementStart(),
316 event->replacementLength());
318 while (d->waitingForSync) {
319 d->compositor->processWaylandEvents();
323 QCoreApplication::processEvents();
326 Qt::InputMethodQueries queries;
327 if (d->surroundingText != oldSurroundText)
328 queries |= Qt::ImSurroundingText;
329 if (d->cursorPosition != oldCursorPosition)
330 queries |= Qt::ImCursorPosition;
331 if (d->anchorPosition != oldAnchorPosition)
332 queries |= Qt::ImAnchorPosition;
333 if (d->absolutePosition != oldAbsolutePosition)
334 queries |= Qt::ImAbsolutePosition;
335 if (d->cursorRectangle != oldCursorRectangle)
336 queries |= Qt::ImCursorRectangle;
337 if (d->preferredLanguage != oldPreferredLanguage)
338 queries |= Qt::ImPreferredLanguage;
339 if (d->hints != oldHints)
340 queries |= Qt::ImHints;
342 emit updateInputMethod(queries);
353 Q_D(QWaylandQtTextInputMethod);
355 QWaylandQtTextInputMethodPrivate::Resource *resource = surface !=
nullptr ? d->resourceMap().value(surface->waylandClient()) :
nullptr;
356 if (d->resource == resource && d->focusedSurface == surface)
359 if (d->resource !=
nullptr && d->focusedSurface !=
nullptr) {
360 d->send_leave(d->resource->handle, d->focusedSurface->resource());
361 d->focusDestroyListener.reset();
364 d->resource = resource;
365 d->focusedSurface = surface;
367 if (d->resource !=
nullptr && d->focusedSurface !=
nullptr) {
368 d->surroundingText.clear();
369 d->cursorPosition = 0;
370 d->anchorPosition = 0;
371 d->absolutePosition = 0;
372 d->cursorRectangle = QRect();
373 d->preferredLanguage.clear();
374 d->hints = Qt::InputMethodHints();
375 d->send_enter(d->resource->handle, d->focusedSurface->resource());
376 sendInputDirectionChanged();
378 sendInputDirectionChanged();
379 d->focusDestroyListener.listenForDestruction(surface->resource());
380 if (d->inputPanelVisible && d->enabledSurfaces.values().contains(surface))
381 qGuiApp->inputMethod()->show();