Support TextInput V3 over v4-wip

Support for v4-wip was not added into any desktop linux compositors, nor
was it ever enabled into the default Qt client builds for clients or
compositor.

TextInputV3 has become the most widely deployed. Whilst changes are
needed, they do not need to be breaking changes. A second iteration of
V3 can add the features we need. This is now in motion upstream.

For cases where QtWaylandCompositor is used, the custom Qt text input
method is preferred to work with the Qt virtual keyboard.

Pick-to: 6.7
Change-Id: I01e2686c67846804c0069f1495952b530547f91c
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
David Edmundson 2023-07-11 13:13:47 +01:00 committed by Eskil Abrahamsen Blomfeldt
parent a55d86be87
commit 8367c68db9
13 changed files with 147 additions and 199 deletions

View File

@ -119,17 +119,18 @@
},
{
"Id": "wayland-text-input-unstable-v4-wip",
"Id": "wayland-text-input-unstable-v3",
"Name": "Wayland Text Input Protocol",
"QDocModule": "qtwaylandcompositor",
"QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
"Files": "text-input-unstable-v4-wip.xml",
"Files": "text-input-unstable-v3.xml",
"Description": "Adds support for compositors to act as input methods and send text to applications.",
"Homepage": "https://wayland.freedesktop.org",
"Version": "unstable v4, WIP",
"LicenseId": "HPND",
"License": "HPND License",
"LicenseFile": "HPND_LICENSE.txt",
"Version": "unstable v3",
"DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/unstable/text-input/text-input-unstable-v3.xml",
"LicenseId": "MIT",
"License": "MIT License",
"LicenseFile": "MIT_LICENSE.txt",
"Copyright": "Copyright © 2012, 2013 Intel Corporation\nCopyright © 2015, 2016 Jan Arne Petersen\nCopyright © 2017, 2018 Red Hat, Inc.\nCopyright © 2018 Purism SPC"
},

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="text_input_unstable_v4_wip">
<protocol name="text_input_unstable_v3">
<copyright>
Copyright © 2012, 2013 Intel Corporation
Copyright © 2015, 2016 Jan Arne Petersen
@ -47,9 +47,9 @@
interface version number is reset.
</description>
<interface name="zwp_text_input_v4" version="1">
<interface name="zwp_text_input_v3" version="1">
<description summary="text input">
The zwp_text_input_v4 interface represents text input and input methods
The zwp_text_input_v3 interface represents text input and input methods
associated with a seat. It provides enter/leave events to follow the
text input focus for a seat.
@ -64,9 +64,9 @@
Lengths must be measured between two valid indices.
Focus moving throughout surfaces will result in the emission of
zwp_text_input_v4.enter and zwp_text_input_v4.leave events. The focused
surface must commit zwp_text_input_v4.enable and
zwp_text_input_v4.disable requests as the keyboard focus moves across
zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
surface must commit zwp_text_input_v3.enable and
zwp_text_input_v3.disable requests as the keyboard focus moves across
editable and non-editable elements of the UI. Those two requests are not
expected to be paired with each other, the compositor must be able to
handle consecutive series of the same request.
@ -91,9 +91,15 @@
This request must be issued every time the active text input changes
to a new one, including within the current surface. Use
zwp_text_input_v4.disable when there is no longer any input focus on
zwp_text_input_v3.disable when there is no longer any input focus on
the current surface.
Clients must not enable more than one text input on the single seat
and should disable the current text input before enabling the new one.
At most one instance of text input may be in enabled state per instance,
Requests to enable the another text input when some text input is active
must be ignored by compositor.
This request resets all state associated with previous enable, disable,
set_surrounding_text, set_text_change_cause, set_content_type, and
set_cursor_rectangle requests, as well as the state associated with
@ -104,11 +110,11 @@
functionality.
State set with this request is double-buffered. It will get applied on
the next zwp_text_input_v4.commit request, and stay valid until the
the next zwp_text_input_v3.commit request, and stay valid until the
next committed enable or disable request.
The changes must be applied by the compositor after issuing a
zwp_text_input_v4.commit request.
zwp_text_input_v3.commit request.
</description>
</request>
@ -118,7 +124,7 @@
there is no focus on any text entry inside the surface).
State set with this request is double-buffered. It will get applied on
the next zwp_text_input_v4.commit request.
the next zwp_text_input_v3.commit request.
</description>
</request>
@ -149,7 +155,7 @@
purpose of this event.
Values set with this request are double-buffered. They will get applied
on the next zwp_text_input_v4.commit request, and stay valid until the
on the next zwp_text_input_v3.commit request, and stay valid until the
next committed enable or disable request.
The initial state for affected fields is empty, meaning that the text
@ -182,7 +188,7 @@
cause describes the source of the change.
The value set with this request is double-buffered. It must be applied
and reset to initial at the next zwp_text_input_v4.commit request.
and reset to initial at the next zwp_text_input_v3.commit request.
The initial value of cause is input_method.
</description>
@ -238,7 +244,7 @@
the behavior.
Values set with this request are double-buffered. They will get applied
on the next zwp_text_input_v4.commit request.
on the next zwp_text_input_v3.commit request.
Subsequent attempts to update them may have no effect. The values
remain valid until the next committed enable or disable request.
@ -261,7 +267,7 @@
issue this request, to signify lack of support to the compositor.
Values set with this request are double-buffered. They will get applied
on the next zwp_text_input_v4.commit request, and stay valid until the
on the next zwp_text_input_v3.commit request, and stay valid until the
next committed enable or disable request.
The initial values describing a cursor rectangle are empty. That means
@ -298,7 +304,7 @@
Neither current nor pending state are modified unless noted otherwise.
The compositor must count the number of commit requests coming from
each zwp_text_input_v4 object and use the count as the serial in done
each zwp_text_input_v3 object and use the count as the serial in done
events.
</description>
</request>
@ -307,6 +313,9 @@
<description summary="enter event">
Notification that this seat's text-input focus is on a certain surface.
If client has created multiple text input objects, compositor must send
this event to all of them.
When the seat has the keyboard capability the text-input focus follows
the keyboard focus. This event sets the current surface for the
text-input object.
@ -321,7 +330,9 @@
set.
The leave notification clears the current surface. It is sent before
the enter notification for the new focus.
the enter notification for the new focus. After leave event, compositor
must ignore requests from any text input instances until next enter
event.
When the seat has the keyboard capability the text-input focus follows
the keyboard focus.
@ -345,7 +356,7 @@
the same, or as a text highlight otherwise.
Values set with this event are double-buffered. They must be applied
and reset to initial on the next zwp_text_input_v4.done event.
and reset to initial on the next zwp_text_input_v3.done event.
The initial value of text is an empty string, and cursor_begin,
cursor_end and cursor_hidden are all 0.
@ -362,7 +373,7 @@
result of some composing (pre-edit).
Values set with this event are double-buffered. They must be applied
and reset to initial on the next zwp_text_input_v4.done event.
and reset to initial on the next zwp_text_input_v3.done event.
The initial value of text is an empty string.
</description>
@ -382,7 +393,7 @@
sequence).
Values set with this event are double-buffered. They must be applied
and reset to initial on the next zwp_text_input_v4.done event.
and reset to initial on the next zwp_text_input_v3.done event.
The initial values of both before_length and after_length are 0.
</description>
@ -408,44 +419,23 @@
5. Insert new preedit text in cursor position.
6. Place cursor inside preedit text.
The serial number reflects the last state of the zwp_text_input_v4
The serial number reflects the last state of the zwp_text_input_v3
object known to the compositor. The value of the serial argument must
be equal to the number of commit requests already issued on that object.
When the client receives a done event with a serial different than the
number of past commit requests, it must proceed as normal, except it
should not change the current state of the zwp_text_input_v4 object.
number of past commit requests, it must proceed with evaluating and
applying the changes as normal, except it should not change the current
state of the zwp_text_input_v3 object. All pending state requests
(set_surrounding_text, set_content_type and set_cursor_rectangle) on
the zwp_text_input_v3 object should be sent and committed after
receiving a zwp_text_input_v3.done event with a matching serial.
</description>
<arg name="serial" type="uint"/>
</event>
<enum name="commit_mode">
<description summary="focus commit mode">
Pre-edit commit mode when the focus widget or the cursor position
is changed.
</description>
<entry name="clear" value="0" summary="pre-edit text is cleared"/>
<entry name="commit" value="1" summary="pre-edit text is committed"/>
</enum>
<event name="preedit_commit_mode">
<description summary="pre-edit commit mode">
Specify how the visible preedit should be handled
when switching the focus widget or changing the cursor position,
whether to commit the preedit text or clear the preedit text.
This is usually used together with the preedit_string event.
The commit behavior is the same for focus switch and
cursor position change.
The parameter mode selects the desired behavior and
its value is one from the commit mode enum.
</description>
<arg name="mode" type="uint" enum="commit_mode"/>
</event>
</interface>
<interface name="zwp_text_input_manager_v4" version="1">
<interface name="zwp_text_input_manager_v3" version="1">
<description summary="text input manager">
A factory for text-input objects. This object is a global singleton.
</description>
@ -460,7 +450,7 @@
<description summary="create a new text input object">
Creates a new text-input object for a given seat.
</description>
<arg name="id" type="new_id" interface="zwp_text_input_v4"/>
<arg name="id" type="new_id" interface="zwp_text_input_v3"/>
<arg name="seat" type="object" interface="wl_seat"/>
</request>
</interface>

View File

@ -4,9 +4,6 @@
# configure.cmake for the QtWaylandGlobalPrivate module
#### Inputs
set(INPUT_wayland_text_input_v4_wip OFF CACHE BOOL "")
#### Libraries
@ -248,12 +245,7 @@ qt_feature("wayland-vulkan-server-buffer" PRIVATE
qt_feature("wayland-datadevice" PRIVATE
CONDITION QT_FEATURE_draganddrop OR QT_FEATURE_clipboard
)
qt_feature("wayland-text-input-v4-wip" PRIVATE
LABEL "Qt Wayland TextInput Protocol V4(WIP)"
PURPOSE "Enables wayland_text_input_unstable_v4(wip)"
)
qt_configure_add_summary_entry(ARGS "wayland-text-input-v4-wip")
qt_configure_add_summary_entry(ARGS "wayland-client")
qt_configure_add_summary_entry(ARGS "wayland-server")
qt_configure_add_summary_section(NAME "Qt Wayland Drivers")

View File

@ -36,6 +36,7 @@ qt_internal_add_module(WaylandClient
qwaylandinputcontext.cpp qwaylandinputcontext_p.h
qwaylandtextinputv1.cpp qwaylandtextinputv1_p.h
qwaylandtextinputv2.cpp qwaylandtextinputv2_p.h
qwaylandtextinputv3.cpp qwaylandtextinputv3_p.h
qwaylandtextinputinterface.cpp qwaylandtextinputinterface_p.h
qwaylandinputdevice.cpp qwaylandinputdevice_p.h
qwaylandinputmethodcontext.cpp qwaylandinputmethodcontext_p.h
@ -87,7 +88,7 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/tablet-unstable-v2.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/text-input-unstable-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/text-input-unstable-v2.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/text-input-unstable-v4-wip.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/text-input-unstable-v3.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/wayland.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/wp-primary-selection-unstable-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/xdg-output-unstable-v1.xml
@ -126,13 +127,6 @@ qt_internal_extend_target(WaylandClient CONDITION QT_FEATURE_tabletevent
qwaylandtabletv2.cpp qwaylandtabletv2_p.h
)
qt_internal_extend_target(WaylandClient CONDITION QT_FEATURE_wayland_text_input_v4_wip
SOURCES
qwaylandtextinputv4.cpp qwaylandtextinputv4_p.h
DEFINES
QT_WAYLAND_TEXT_INPUT_V4_WIP=1
)
qt_internal_extend_target(WaylandClient CONDITION QT_FEATURE_clipboard
SOURCES
qwaylandclipboard.cpp qwaylandclipboard_p.h

View File

@ -26,9 +26,7 @@
#include "qwaylandhardwareintegration_p.h"
#include "qwaylandtextinputv1_p.h"
#include "qwaylandtextinputv2_p.h"
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
#include "qwaylandtextinputv4_p.h"
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
#include "qwaylandtextinputv3_p.h"
#include "qwaylandinputcontext_p.h"
#include "qwaylandinputmethodcontext_p.h"
@ -47,7 +45,7 @@
#include <QtWaylandClient/private/qwayland-text-input-unstable-v1.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v4-wip.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h>
#include <QtWaylandClient/private/qwayland-wp-primary-selection-unstable-v1.h>
#include <QtWaylandClient/private/qwayland-qt-text-input-method-unstable-v1.h>
#include <QtWaylandClient/private/qwayland-fractional-scale-v1.h>
@ -556,15 +554,13 @@ void QWaylandDisplay::checkTextInputProtocol()
{
QStringList tips, timps; // for text input protocols and text input manager protocols
tips << QLatin1String(QtWayland::qt_text_input_method_v1::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_v3::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_v2::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_v1::interface()->name);
timps << QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_manager_v3::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_manager_v2::interface()->name)
<< QLatin1String(QtWayland::zwp_text_input_manager_v1::interface()->name);
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
tips << QLatin1String(QtWayland::zwp_text_input_v4::interface()->name);
timps << QLatin1String(QtWayland::zwp_text_input_manager_v4::interface()->name);
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
QString tiProtocols = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_TEXT_INPUT_PROTOCOL"));
qCDebug(lcQpaWayland) << "QT_WAYLAND_TEXT_INPUT_PROTOCOL=" << tiProtocols;
@ -656,9 +652,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
if (mTextInputManagerIndex < INT_MAX) {
mGlobals.textInputManagerv1.reset();
mGlobals.textInputManagerv2.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv3.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(nullptr);
}
@ -678,9 +672,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
if (mTextInputManagerIndex < INT_MAX) {
mGlobals.textInputMethodManager.reset();
mGlobals.textInputManagerv2.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv3.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(nullptr);
}
@ -702,9 +694,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
if (mTextInputManagerIndex < INT_MAX) {
mGlobals.textInputMethodManager.reset();
mGlobals.textInputManagerv1.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
mGlobals.textInputManagerv3.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(nullptr);
}
@ -716,10 +706,9 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
this, mGlobals.textInputManagerv2->get_text_input(inputDevice->wl_seat())));
mWaylandIntegration->reconfigureInputContext();
mTextInputManagerIndex = mTextInputManagerList.indexOf(interface);
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
} else if (interface == QLatin1String(QtWayland::zwp_text_input_manager_v4::interface()->name)
} else if (interface == QLatin1String(QtWayland::zwp_text_input_manager_v3::interface()->name)
&& (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) {
qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v4";
qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v3";
if (mTextInputManagerIndex < INT_MAX) {
mGlobals.textInputMethodManager.reset();
mGlobals.textInputManagerv2.reset();
@ -727,15 +716,15 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
inputDevice->setTextInputMethod(nullptr);
}
mGlobals.textInputManagerv4.reset(
new QtWayland::zwp_text_input_manager_v4(registry, id, 1));
mGlobals.textInputManagerv3.reset(
new QtWayland::zwp_text_input_manager_v3(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(new QWaylandTextInputv4(
this, mGlobals.textInputManagerv4->get_text_input(inputDevice->wl_seat())));
inputDevice->setTextInput(new QWaylandTextInputv3(
this, mGlobals.textInputManagerv3->get_text_input(inputDevice->wl_seat())));
mWaylandIntegration->reconfigureInputContext();
mTextInputManagerIndex = mTextInputManagerList.indexOf(interface);
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
} else if (interface == QLatin1String(QWaylandHardwareIntegration::interface()->name)) {
}else if (interface == QLatin1String(QWaylandHardwareIntegration::interface()->name)) {
bool disableHardwareIntegration = qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_HW_INTEGRATION");
if (!disableHardwareIntegration) {
mGlobals.hardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id));
@ -805,14 +794,12 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
inputDevice->setTextInput(nullptr);
mWaylandIntegration->reconfigureInputContext();
}
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v4::interface()->name)) {
mGlobals.textInputManagerv4.reset();
if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v3::interface()->name)) {
mGlobals.textInputManagerv3.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(nullptr);
mWaylandIntegration->reconfigureInputContext();
}
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
if (global.interface == QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name)) {
mGlobals.textInputMethodManager.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))

View File

@ -49,7 +49,7 @@ namespace QtWayland {
class qt_surface_extension;
class zwp_text_input_manager_v1;
class zwp_text_input_manager_v2;
class zwp_text_input_manager_v4;
class zwp_text_input_manager_v3;
class qt_text_input_method_manager_v1;
class wp_cursor_shape_manager_v1;
class wp_fractional_scale_manager_v1;
@ -176,9 +176,9 @@ public:
{
return mGlobals.textInputManagerv2.get();
}
QtWayland::zwp_text_input_manager_v4 *textInputManagerv4() const
QtWayland::zwp_text_input_manager_v3 *textInputManagerv3() const
{
return mGlobals.textInputManagerv4.get();
return mGlobals.textInputManagerv3.get();
}
QWaylandHardwareIntegration *hardwareIntegration() const
{
@ -205,6 +205,7 @@ public:
return mGlobals.xdgToplevelDragManager.get();
}
struct RegistryGlobal {
uint32_t id;
QString interface;
@ -329,7 +330,7 @@ private:
std::unique_ptr<QtWayland::qt_text_input_method_manager_v1> textInputMethodManager;
std::unique_ptr<QtWayland::zwp_text_input_manager_v1> textInputManagerv1;
std::unique_ptr<QtWayland::zwp_text_input_manager_v2> textInputManagerv2;
std::unique_ptr<QtWayland::zwp_text_input_manager_v4> textInputManagerv4;
std::unique_ptr<QtWayland::zwp_text_input_manager_v3> textInputManagerv3;
std::unique_ptr<QWaylandHardwareIntegration> hardwareIntegration;
std::unique_ptr<QWaylandXdgOutputManagerV1> xdgOutputManager;
std::unique_ptr<QtWayland::wp_viewporter> viewporter;
@ -337,7 +338,6 @@ private:
std::unique_ptr<QtWayland::wp_cursor_shape_manager_v1> cursorShapeManager;
std::unique_ptr<QtWayland::qt_toplevel_drag_manager_v1> xdgToplevelDragManager;
} mGlobals;
int mFd = -1;
int mWritableNotificationFd = -1;
QList<RegistryGlobal> mRegistryGlobals;

View File

@ -35,11 +35,7 @@ QWaylandInputContext::~QWaylandInputContext()
bool QWaylandInputContext::isValid() const
{
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
return mDisplay->textInputManagerv2() != nullptr || mDisplay->textInputManagerv1() != nullptr || mDisplay->textInputManagerv4() != nullptr;
#else // QT_WAYLAND_TEXT_INPUT_V4_WIP
return mDisplay->textInputManagerv2() != nullptr || mDisplay->textInputManagerv1() != nullptr;
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
return mDisplay->textInputManagerv2() != nullptr || mDisplay->textInputManagerv1() != nullptr || mDisplay->textInputManagerv3() != nullptr;
}
void QWaylandInputContext::reset()

View File

@ -4,6 +4,7 @@
#include "qwaylandinputdevice_p.h"
#include "qwaylandintegration_p.h"
#include "qwaylandtextinputv3_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandsurface_p.h"
#include "qwaylandbuffer_p.h"
@ -25,9 +26,6 @@
#include "qwaylandshmbackingstore_p.h"
#include "qwaylandtextinputv1_p.h"
#include "qwaylandtextinputv2_p.h"
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
#include "qwaylandtextinputv4_p.h"
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
#include "qwaylandtextinputinterface_p.h"
#include "qwaylandinputcontext_p.h"
#include "qwaylandinputmethodcontext_p.h"
@ -408,10 +406,8 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version,
if (mQDisplay->textInputManagerv2())
mTextInput.reset(new QWaylandTextInputv2(mQDisplay, mQDisplay->textInputManagerv2()->get_text_input(wl_seat())));
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
if (mQDisplay->textInputManagerv4())
mTextInput.reset(new QWaylandTextInputv4(mQDisplay, mQDisplay->textInputManagerv4()->get_text_input(wl_seat())));
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
if (mQDisplay->textInputManagerv3())
mTextInput.reset(new QWaylandTextInputv3(mQDisplay, mQDisplay->textInputManagerv3()->get_text_input(wl_seat())));
if (mQDisplay->textInputMethodManager())
mTextInputMethod.reset(new QWaylandTextInputMethod(mQDisplay, mQDisplay->textInputMethodManager()->get_text_input_method(wl_seat())));

View File

@ -470,11 +470,7 @@ void QWaylandIntegration::reconfigureInputContext()
if (!mDisplay->isClientSideInputContextRequested()) {
if (mDisplay->textInputMethodManager() != nullptr)
mInputContext.reset(new QWaylandInputMethodContext(mDisplay.data()));
#if QT_WAYLAND_TEXT_INPUT_V4_WIP
else if (mDisplay->textInputManagerv1() != nullptr || mDisplay->textInputManagerv2() != nullptr || mDisplay->textInputManagerv4() != nullptr)
#else // QT_WAYLAND_TEXT_INPUT_V4_WIP
else if (mDisplay->textInputManagerv1() != nullptr || mDisplay->textInputManagerv2() != nullptr)
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
else if (mDisplay->textInputManagerv1() != nullptr || mDisplay->textInputManagerv2() != nullptr || mDisplay->textInputManagerv3() != nullptr)
mInputContext.reset(new QWaylandInputContext(mDisplay.data()));
} else {
mInputContext.reset(QPlatformInputContextFactory::create(requested));

View File

@ -1,7 +1,7 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwaylandtextinputv4_p.h"
#include "qwaylandtextinputv3_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandinputmethodeventbuilder_p.h"
@ -18,20 +18,20 @@ Q_LOGGING_CATEGORY(qLcQpaWaylandTextInput, "qt.qpa.wayland.textinput")
namespace QtWaylandClient {
QWaylandTextInputv4::QWaylandTextInputv4(QWaylandDisplay *display,
struct ::zwp_text_input_v4 *text_input)
: QtWayland::zwp_text_input_v4(text_input)
QWaylandTextInputv3::QWaylandTextInputv3(QWaylandDisplay *display,
struct ::zwp_text_input_v3 *text_input)
: QtWayland::zwp_text_input_v3(text_input)
, m_display(display)
{
}
QWaylandTextInputv4::~QWaylandTextInputv4()
QWaylandTextInputv3::~QWaylandTextInputv3()
{
}
namespace {
const Qt::InputMethodQueries supportedQueries4 = Qt::ImEnabled |
const Qt::InputMethodQueries supportedQueries3 = Qt::ImEnabled |
Qt::ImSurroundingText |
Qt::ImCursorPosition |
Qt::ImAnchorPosition |
@ -39,7 +39,7 @@ const Qt::InputMethodQueries supportedQueries4 = Qt::ImEnabled |
Qt::ImCursorRectangle;
}
void QWaylandTextInputv4::zwp_text_input_v4_enter(struct ::wl_surface *surface)
void QWaylandTextInputv3::zwp_text_input_v3_enter(struct ::wl_surface *surface)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
@ -51,10 +51,10 @@ void QWaylandTextInputv4::zwp_text_input_v4_enter(struct ::wl_surface *surface)
m_pendingDeleteAfterText = 0;
enable();
updateState(supportedQueries4, update_state_enter);
updateState(supportedQueries3, update_state_enter);
}
void QWaylandTextInputv4::zwp_text_input_v4_leave(struct ::wl_surface *surface)
void QWaylandTextInputv3::zwp_text_input_v3_leave(struct ::wl_surface *surface)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
@ -63,10 +63,6 @@ void QWaylandTextInputv4::zwp_text_input_v4_leave(struct ::wl_surface *surface)
return;
}
// QTBUG-97248: check commit_mode
// Currently text-input-unstable-v4-wip is implemented with preedit_commit_mode
// 'commit'
m_currentPreeditString.clear();
m_surface = nullptr;
@ -76,7 +72,7 @@ void QWaylandTextInputv4::zwp_text_input_v4_leave(struct ::wl_surface *surface)
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "Done";
}
void QWaylandTextInputv4::zwp_text_input_v4_preedit_string(const QString &text, int32_t cursorBegin, int32_t cursorEnd)
void QWaylandTextInputv3::zwp_text_input_v3_preedit_string(const QString &text, int32_t cursorBegin, int32_t cursorEnd)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << text << cursorBegin << cursorEnd;
@ -88,7 +84,7 @@ void QWaylandTextInputv4::zwp_text_input_v4_preedit_string(const QString &text,
m_pendingPreeditString.cursorEnd = cursorEnd;
}
void QWaylandTextInputv4::zwp_text_input_v4_commit_string(const QString &text)
void QWaylandTextInputv3::zwp_text_input_v3_commit_string(const QString &text)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << text;
@ -98,7 +94,7 @@ void QWaylandTextInputv4::zwp_text_input_v4_commit_string(const QString &text)
m_pendingCommitString = text;
}
void QWaylandTextInputv4::zwp_text_input_v4_delete_surrounding_text(uint32_t beforeText, uint32_t afterText)
void QWaylandTextInputv3::zwp_text_input_v3_delete_surrounding_text(uint32_t beforeText, uint32_t afterText)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << beforeText << afterText;
@ -109,12 +105,12 @@ void QWaylandTextInputv4::zwp_text_input_v4_delete_surrounding_text(uint32_t bef
m_pendingDeleteAfterText = QWaylandInputMethodEventBuilder::indexFromWayland(m_surroundingText, afterText);
}
void QWaylandTextInputv4::zwp_text_input_v4_done(uint32_t serial)
void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "with serial" << serial << m_currentSerial;
// This is a case of double click.
// text_input_v4 will ignore this done signal and just keep the selection of the clicked word.
// text_input_v3 will ignore this done signal and just keep the selection of the clicked word.
if (m_cursorPos != m_anchorPos && (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0)) {
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "Ignore done";
m_pendingDeleteBeforeText = 0;
@ -177,22 +173,22 @@ void QWaylandTextInputv4::zwp_text_input_v4_done(uint32_t serial)
QCoreApplication::sendEvent(focusObject, &event);
if (serial == m_currentSerial)
updateState(supportedQueries4, update_state_full);
updateState(supportedQueries3, update_state_full);
}
void QWaylandTextInputv4::reset()
void QWaylandTextInputv3::reset()
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
m_pendingPreeditString.clear();
}
void QWaylandTextInputv4::enableSurface(::wl_surface *)
void QWaylandTextInputv3::enableSurface(::wl_surface *)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
}
void QWaylandTextInputv4::disableSurface(::wl_surface *surface)
void QWaylandTextInputv3::disableSurface(::wl_surface *surface)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
@ -202,15 +198,15 @@ void QWaylandTextInputv4::disableSurface(::wl_surface *surface)
}
}
void QWaylandTextInputv4::commit()
void QWaylandTextInputv3::commit()
{
m_currentSerial = (m_currentSerial < UINT_MAX) ? m_currentSerial + 1U: 0U;
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "with serial" << m_currentSerial;
QtWayland::zwp_text_input_v4::commit();
QtWayland::zwp_text_input_v3::commit();
}
void QWaylandTextInputv4::updateState(Qt::InputMethodQueries queries, uint32_t flags)
void QWaylandTextInputv3::updateState(Qt::InputMethodQueries queries, uint32_t flags)
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << queries << flags;
@ -225,7 +221,7 @@ void QWaylandTextInputv4::updateState(Qt::InputMethodQueries queries, uint32_t f
if (!surface || (surface != m_surface))
return;
queries &= supportedQueries4;
queries &= supportedQueries3;
bool needsCommit = false;
QInputMethodQueryEvent event(queries);
@ -319,7 +315,7 @@ void QWaylandTextInputv4::updateState(Qt::InputMethodQueries queries, uint32_t f
}
if (queries & Qt::ImHints) {
QWaylandInputMethodContentType contentType = QWaylandInputMethodContentType::convertV4(static_cast<Qt::InputMethodHints>(event.value(Qt::ImHints).toInt()));
QWaylandInputMethodContentType contentType = QWaylandInputMethodContentType::convertV3(static_cast<Qt::InputMethodHints>(event.value(Qt::ImHints).toInt()));
qCDebug(qLcQpaWaylandTextInput) << m_contentHint << contentType.hint;
qCDebug(qLcQpaWaylandTextInput) << m_contentPurpose << contentType.purpose;
@ -338,33 +334,33 @@ void QWaylandTextInputv4::updateState(Qt::InputMethodQueries queries, uint32_t f
commit();
}
void QWaylandTextInputv4::setCursorInsidePreedit(int cursor)
void QWaylandTextInputv3::setCursorInsidePreedit(int cursor)
{
Q_UNUSED(cursor);
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV4: Input protocol \"text-input-unstable-v4-wip\" does not support setting cursor inside preedit. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV3: Input protocol \"text-input-unstable-v3\" does not support setting cursor inside preedit. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
}
bool QWaylandTextInputv4::isInputPanelVisible() const
bool QWaylandTextInputv3::isInputPanelVisible() const
{
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV4: Input protocol \"text-input-unstable-v4-wip\" does not support querying input method visibility. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV3: Input protocol \"text-input-unstable-v3\" does not support querying input method visibility. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
return false;
}
QRectF QWaylandTextInputv4::keyboardRect() const
QRectF QWaylandTextInputv3::keyboardRect() const
{
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
return m_cursorRect;
}
QLocale QWaylandTextInputv4::locale() const
QLocale QWaylandTextInputv3::locale() const
{
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV4: Input protocol \"text-input-unstable-v4-wip\" does not support querying input language. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV3: Input protocol \"text-input-unstable-v3\" does not support querying input language. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
return QLocale();
}
Qt::LayoutDirection QWaylandTextInputv4::inputDirection() const
Qt::LayoutDirection QWaylandTextInputv3::inputDirection() const
{
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV4: Input protocol \"text-input-unstable-v4-wip\" does not support querying input direction. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
qCWarning(qLcQpaWaylandTextInput) << "QWaylandTextInputV3: Input protocol \"text-input-unstable-v3\" does not support querying input direction. Use qt-text-input-method-unstable-v1 instead for full support of Qt input method events.";
return Qt::LeftToRight;
}

View File

@ -1,8 +1,8 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWAYLANDTEXTINPUTV4_P_H
#define QWAYLANDTEXTINPUTV4_P_H
#ifndef QWAYLANDTEXTINPUTV3_P_H
#define QWAYLANDTEXTINPUTV3_P_H
//
// W A R N I N G
@ -16,7 +16,7 @@
//
#include "qwaylandtextinputinterface_p.h"
#include <QtWaylandClient/private/qwayland-text-input-unstable-v4-wip.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h>
#include <qwaylandinputmethodeventbuilder_p.h>
#include <QLoggingCategory>
@ -31,11 +31,11 @@ namespace QtWaylandClient {
class QWaylandDisplay;
class QWaylandTextInputv4 : public QtWayland::zwp_text_input_v4, public QWaylandTextInputInterface
class QWaylandTextInputv3 : public QtWayland::zwp_text_input_v3, public QWaylandTextInputInterface
{
public:
QWaylandTextInputv4(QWaylandDisplay *display, struct ::zwp_text_input_v4 *text_input);
~QWaylandTextInputv4() override;
QWaylandTextInputv3(QWaylandDisplay *display, struct ::zwp_text_input_v3 *text_input);
~QWaylandTextInputv3() override;
void reset() override;
void commit() override;
@ -53,12 +53,12 @@ public:
void disableSurface(::wl_surface *surface) override;
protected:
void zwp_text_input_v4_enter(struct ::wl_surface *surface) override;
void zwp_text_input_v4_leave(struct ::wl_surface *surface) override;
void zwp_text_input_v4_preedit_string(const QString &text, int32_t cursor_begin, int32_t cursor_end) override;
void zwp_text_input_v4_commit_string(const QString &text) override;
void zwp_text_input_v4_delete_surrounding_text(uint32_t before_length, uint32_t after_length) override;
void zwp_text_input_v4_done(uint32_t serial) override;
void zwp_text_input_v3_enter(struct ::wl_surface *surface) override;
void zwp_text_input_v3_leave(struct ::wl_surface *surface) override;
void zwp_text_input_v3_preedit_string(const QString &text, int32_t cursor_begin, int32_t cursor_end) override;
void zwp_text_input_v3_commit_string(const QString &text) override;
void zwp_text_input_v3_delete_surrounding_text(uint32_t before_length, uint32_t after_length) override;
void zwp_text_input_v3_done(uint32_t serial) override;
private:
QWaylandDisplay *m_display;
@ -101,4 +101,4 @@ private:
QT_END_NAMESPACE
#endif // QWAYLANDTEXTINPUTV4_P_H
#endif // QWAYLANDTEXTINPUTV3_P_H

View File

@ -11,10 +11,10 @@
#ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
#include <QtWaylandCompositor/private/qwayland-server-text-input-unstable-v2.h>
#include <QtWaylandCompositor/private/qwayland-server-text-input-unstable-v4-wip.h>
#include <QtWaylandCompositor/private/qwayland-server-text-input-unstable-v3.h>
#else
#include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v4-wip.h>
#include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h>
#endif
QT_BEGIN_NAMESPACE
@ -218,55 +218,55 @@ QWaylandInputMethodContentType QWaylandInputMethodContentType::convert(Qt::Input
return QWaylandInputMethodContentType{hint, purpose};
}
QWaylandInputMethodContentType QWaylandInputMethodContentType::convertV4(Qt::InputMethodHints hints)
QWaylandInputMethodContentType QWaylandInputMethodContentType::convertV3(Qt::InputMethodHints hints)
{
uint32_t hint = ZWP_TEXT_INPUT_V4_CONTENT_HINT_NONE;
uint32_t purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_NORMAL;
uint32_t hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE;
uint32_t purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
if (hints & Qt::ImhHiddenText)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_HIDDEN_TEXT;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_HIDDEN_TEXT;
if (hints & Qt::ImhSensitiveData)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_SENSITIVE_DATA;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA;
if ((hints & Qt::ImhNoAutoUppercase) == 0)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_AUTO_CAPITALIZATION;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION;
if (hints & Qt::ImhPreferNumbers) {
// Nothing yet
}
if (hints & Qt::ImhPreferUppercase)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_UPPERCASE;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_UPPERCASE;
if (hints & Qt::ImhPreferLowercase)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_LOWERCASE;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_LOWERCASE;
if ((hints & Qt::ImhNoPredictiveText) == 0) {
hint |= (ZWP_TEXT_INPUT_V4_CONTENT_HINT_COMPLETION
| ZWP_TEXT_INPUT_V4_CONTENT_HINT_SPELLCHECK);
hint |= (ZWP_TEXT_INPUT_V3_CONTENT_HINT_COMPLETION
| ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK);
}
if ((hints & Qt::ImhDate) && (hints & Qt::ImhTime) == 0)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_DATE;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE;
else if ((hints & Qt::ImhDate) && (hints & Qt::ImhTime))
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_DATETIME;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME;
else if ((hints & Qt::ImhDate) == 0 && (hints & Qt::ImhTime))
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_TIME;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TIME;
if (hints & Qt::ImhPreferLatin)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_LATIN;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_LATIN;
if (hints & Qt::ImhMultiLine)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_MULTILINE;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_MULTILINE;
if (hints & Qt::ImhDigitsOnly)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_DIGITS;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS;
if (hints & Qt::ImhFormattedNumbersOnly)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_NUMBER;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER;
if (hints & Qt::ImhUppercaseOnly)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_UPPERCASE;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_UPPERCASE;
if (hints & Qt::ImhLowercaseOnly)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_LOWERCASE;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_LOWERCASE;
if (hints & Qt::ImhDialableCharactersOnly)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_PHONE;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE;
if (hints & Qt::ImhEmailCharactersOnly)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_EMAIL;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL;
if (hints & Qt::ImhUrlCharactersOnly)
purpose = ZWP_TEXT_INPUT_V4_CONTENT_PURPOSE_URL;
purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL;
if (hints & Qt::ImhLatinOnly)
hint |= ZWP_TEXT_INPUT_V4_CONTENT_HINT_LATIN;
hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_LATIN;
return QWaylandInputMethodContentType{hint, purpose};
}

View File

@ -47,7 +47,7 @@ struct QWaylandInputMethodContentType {
uint32_t purpose = 0;
static QWaylandInputMethodContentType convert(Qt::InputMethodHints hints);
static QWaylandInputMethodContentType convertV4(Qt::InputMethodHints hints);
static QWaylandInputMethodContentType convertV3(Qt::InputMethodHints hints);
};