Merge branch 'im_keyboard_again' into 'main'

input method: simpler keyboard handling

See merge request wayland/wayland-protocols!427
This commit is contained in:
DorotaC 2025-12-16 20:52:24 +00:00
commit ef6756c136

View file

@ -70,6 +70,7 @@
<enum name="error">
<entry name="surface_has_role" value="0x0" summary="surface already has a role"/>
<entry name="inactive" value="0x1" summary="operation requires the input method to be active"/>
<entry name="keyboard_already_bound" value="0x3" summary="this input method already has a keyboard" since = "3"/>
</enum>
<event name="activate">
@ -85,6 +86,8 @@
as the state associated with set_preedit_string, commit_string, and
delete_surrounding_text requests, and destroys any existing input_popup_surface objects.
In addition, it marks the xx_input_method_v1 object as active.
This marks the wl_keyboard bound to this input method as enabled. That means the wl_keyboard starts receiving events originally destined for the surface which activated this input method. Those events must get filtered according to .keyboard_filter (using a mechanism outside the scope of this protocol) before finally reaching the original target surface. See .keyboard_filter.
The surrounding_text, and content_type events must follow before the
next done event if the text input supports the respective
@ -102,6 +105,7 @@
This event marks the xx_input_method_v1 object as inactive.
compositor must destroy all existing xx_input_popup_surface_v2 objects.
This event marks the wl_keyboard bound to this input method for deactivation. It will no longer receive events, and the original surface receives all events again as normal, until the next .activate.
This event resets all state associated with previous
surrounding_text, text_change_cause, and content_type events, as well
@ -385,7 +389,7 @@
</description>
<arg name="serial" type="uint"/>
</request>
<request name="get_input_popup_surface" since="2">
<description summary="create popup surface">
Creates a new xx_input_popup_surface_v2 object wrapping a given
@ -401,7 +405,44 @@
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="positioner" type="object" interface="xx_input_popup_positioner_v1"/>
</request>
<request name="keyboard_bind" since="3">
<description summary="Bind an intercepting keyboard">
Bind a keyboard for capturing events for text input.
When a keyboard is bound, the compositor must redirect to it the input events intended for the text input client surface. This keyboard receives no other events.
See input_method_keyboard.filter.
The text input client might use a wl_keyboard object of a different version than the one used by the input method. If the text input client uses a lower version, the events sent by the compositor to the bound keyboard must simply obey the semantics of the lower version.
If the text input client uses a higher version, the input method could be unable to interpret some of the events. The compositor may temporarily disable the binding while notifying the user.
The compositor should select a version of wl_keyboard interface not higher than the one supported by the input method and translate client's events to that version for the purpose of filtering, and back when they are passed through.
In every case, the input_method_keyboard.notify_version event should be issued, carrying the version actually used for filtering.
This request binds a wl_keyboard object to the input method.
The wl_keyboard must not be already bound to another interface.
The wl_keyboard must only receive events between committed .activate and .deactivate.
The surface argument represents an arbitrary wl_surface. When issuing wl_keyboard.enter and wl_keyboard.leave on the bound wl_keyboard, it must replace the original surface argument with the one provided by the input method in this request.
Because the wl_keyboard.enter and wl_keyboard.leave events require a surface as the target, one must be provided even if the input method doesn't display one. A dummy one is sufficient. The provided wl_surface will not be used for any other purpose than explained above.
The surface must outlive the input method.
This request creates an input_method_keyboard object, which contains functionality additional to wl_keyboard and specific to input method.
NOTE: This feature works much better with compositor-side key repeat introduced in wl_seat version 10. This protocol doesn't provide controls for filtering repeat key events generated client-side.
A compositor implementing this protocol should implement compositor-side key repeat.
This request takes effect immediately.
Attempting to bind two keyboards at the same time must cause the already_bound error.
<!-- This limitation could be lifted, although in smithay it would cause some extra complexity -->
</description>
<arg name="keyboard" type="object" interface="wl_keyboard" />
<arg name="surface" type="object" interface="wl_surface" />
<arg name="extensions" type="new_id" interface="xx_input_method_keyboard_v1"/>
</request>
<event name="unavailable">
<description summary="input method unavailable">
The input method ceased to be available.
@ -427,6 +468,97 @@
</request>
</interface>
<interface name="xx_input_method_keyboard_v1" version="3">
<description summary="input-method keyboard functions">
Contains input method specific functionality on top of wl_keyboard.
</description>
<enum name="error">
<entry name="invalid_serial" value="0x1" summary="compositor received serial not adhering to requirements"/>
<entry name="not_bound" value="0x2" summary="this input method has no keyboard"/>
<entry name="in_use" value="0x3" summary="this keyboard is already used for something else"/>
<entry name="invalid_filter_action" value="0x4" summary="filter action not suitable for event"/>
</enum>
<request name="unbind">
<description summary="Stop capturing">
Unbind the keyboard for capturing events for text input.
Unbinds the previously bound keyboard. the compositor must no longer redirect to it the input events intended for the text client input surface. Events that the input method client has not yet responded to are treated as if they received the "passthrough" action.
This request takes effect immediately.
Issuing this request when there is no currently bound keyboard must cause the keyboard_not_bound error.
</description>
</request>
<event name="notify_version" since="3">
<description summary="wl_keyboard version used for filtering">
Notifies the input method about the semantics used for the bound keyboard interface.
This event allows the input method to anticipate the kinds of events its bound keyboard might receive, for example repeated key events which may not be supported by the client.
This event must be sent in the first commit sequence after binding a new keyboard, and then in the first commit sequence after every activate event.
The special version value of 0 means that keyboard event filtering is inactive. The compositor must not issue any keyboard events while version equals 0.
Values set with this event are stored per-input_method_keyboard instance and double-buffered. They will get applied
on the next xx_input_method_v1.done event on the parent input_method object.
The initial value for version is 0.
</description>
<arg name="version" type="uint"/>
</event>
<enum name="filter_action">
<entry name="consume" value="0" summary="consume the key event"/>
<entry name="passthrough" value="1" summary="pass the key event to the text input client"/>
</enum>
<request name="filter">
<description summary="decide the processing of a keyboard event">
This request controls the filtering of keyboard input events reaching the application.
Background:
Whenever the input method is activated, the compositor must start sending it keyboard events intended for the text-input client, so that the input method can be controlled using a keyboard.
Traditionally, from the user perspective, input methods receive keys as if they were an overlay: keys which are interesting to the input method gain a special input method meaning, all others work as usual.
Together with the bound wl_keyboard, this request makes this possible by letting the input method indicate which events it is interested in.
Conceptually, when a wl_keyboard is bound to the input_method, the compositor prevents all keyboard events directed to the text input client from reaching it. They are delayed until the input_method decides how to filter them using the .filter request.
Usage:
This request is to be issued for events received on the wl_keyboard supplied to input_method_manager.keyboard_bind.
This request must be issued after every (see Exceptions) event received on the keyboard instance, and it must reference that event's serial.
If action is passthrough, then the compositor must re-issue the event to the original surface. Otherwise, the compositor must discard the event.
Exceptions:
If the event is other than key event or contains no serial, the input method client must respond with a passthrough action. The compositor may apply the event before receiving the corresponding .filter request, as long as events sent to the target remain in order.
The compositor must issue the invalid_filter_action error if it receives consume on an event described above.
As of wl_keyboard v10 and input_method v3, the only event that may be consumed is the wl_keyboard.key event.
Because some events have no serial, they can not be unambiguously confirmed by the client. The compositor must assume those events have been confirmed in the correct order relative to surrounding events.
<!-- Alternative: compositor assumes the events are confirmed automatically. Downside: harder to specify the model of ordering events when some serials are missing. -->
Sequence:
The keyboard begins to receive events after input_method.activate is committed.
The valid serial is the serial of the oldest wl_keyboard event which has been sent after input_method.activate but which hasn't yet received a .filter confirmation.
The compositor may raise the invalid_serial error in response toevents with serials it had not issued.
The compositor must ignore events with all other serials. (Particularly, this means events with repeating serials are accepted normally and are not ignored).
Events must be filtered in order.
</description>
<arg name="serial" type="uint"/>
<arg name="action" type="uint" enum="filter_action"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the keyboard">
Destroys the xx_input_method_keyboard_v1 object and any associated child
objects.
</description>
</request>
</interface>
<interface name="xx_input_popup_surface_v2" version="1">
<description summary="popup surface">
An input method popup surface is a short-lived, temporary surface.