feat(wayland): text input through zwp_text_input_v3
A window can now say that a text field has the focus and where its caret is — Window::SetTextInput(active, caret rectangle in physical pixels, purpose) — which is what opens the on-screen keyboard on a phone (Maliit under KWin, squeekboard under phoc). What the input method produces comes back as events: committed text as onTextInput, the composing text as onPreedit (empty clears it), deletions around the cursor as onTextInputDelete; done() applies them in the protocol's order. The state a window wants is remembered and sent again whenever the keyboard focus returns to it. The protocol's client code is generated with wayland-scanner 1.26.0 from wayland-protocols' text-input-unstable-v3.xml, under lib/ like the others.
This commit is contained in:
parent
aed6142cce
commit
678f38964f
8 changed files with 1355 additions and 0 deletions
|
|
@ -12,6 +12,7 @@ module;
|
|||
#include "../lib/wayland-xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include "../lib/fractional-scale-v1.h"
|
||||
#include "../lib/viewporter.h"
|
||||
#include "../lib/text-input-unstable-v3-client-protocol.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#endif
|
||||
export module Crafter.Graphics:Device;
|
||||
|
|
@ -76,6 +77,22 @@ export namespace Crafter {
|
|||
// whole detent yet is carried here so smooth-scroll devices add up
|
||||
// across events. Reset on pointer leave.
|
||||
inline static double scrollDetentRemainder = 0.0;
|
||||
// zwp_text_input_v3: one object per seat; the compositor says which
|
||||
// surface it follows (enter/leave), the events are state that done()
|
||||
// applies as a whole.
|
||||
inline static zwp_text_input_manager_v3* textInputManager = nullptr;
|
||||
inline static zwp_text_input_v3* textInput = nullptr;
|
||||
inline static Window* textInputWindow = nullptr;
|
||||
inline static std::string textInputPreedit;
|
||||
inline static std::string textInputShownPreedit; // what the window was last told
|
||||
inline static std::string textInputCommit;
|
||||
inline static std::uint32_t textInputDeleteBefore = 0;
|
||||
inline static std::uint32_t textInputDeleteAfter = 0;
|
||||
inline static bool textInputHasPreedit = false;
|
||||
inline static bool textInputHasCommit = false;
|
||||
inline static bool textInputHasDelete = false;
|
||||
// Sends the window's wanted text-input state when it has the focus.
|
||||
static void ApplyTextInput(Window* window);
|
||||
|
||||
static void seat_handle_capabilities(void* data, wl_seat* seat, uint32_t capabilities);
|
||||
static void xdg_surface_handle_preferred_scale(void* data, wp_fractional_scale_v1*, std::uint32_t scale);
|
||||
|
|
@ -98,6 +115,12 @@ export namespace Crafter {
|
|||
static void touch_motion(void* data, wl_touch* touch, std::uint32_t time, std::int32_t id, wl_fixed_t x, wl_fixed_t y);
|
||||
static void touch_frame(void* data, wl_touch* touch);
|
||||
static void touch_cancel(void* data, wl_touch* touch);
|
||||
static void text_input_enter(void* data, zwp_text_input_v3* textInput, wl_surface* surface);
|
||||
static void text_input_leave(void* data, zwp_text_input_v3* textInput, wl_surface* surface);
|
||||
static void text_input_preedit(void* data, zwp_text_input_v3* textInput, const char* text, std::int32_t cursorBegin, std::int32_t cursorEnd);
|
||||
static void text_input_commit(void* data, zwp_text_input_v3* textInput, const char* text);
|
||||
static void text_input_delete(void* data, zwp_text_input_v3* textInput, std::uint32_t before, std::uint32_t after);
|
||||
static void text_input_done(void* data, zwp_text_input_v3* textInput, std::uint32_t serial);
|
||||
|
||||
constexpr static wl_pointer_listener pointer_listener = {
|
||||
.enter = PointerListenerHandleEnter,
|
||||
|
|
@ -113,6 +136,14 @@ export namespace Crafter {
|
|||
.frame = touch_frame,
|
||||
.cancel = touch_cancel,
|
||||
};
|
||||
constexpr static zwp_text_input_v3_listener text_input_listener = {
|
||||
.enter = text_input_enter,
|
||||
.leave = text_input_leave,
|
||||
.preedit_string = text_input_preedit,
|
||||
.commit_string = text_input_commit,
|
||||
.delete_surrounding_text = text_input_delete,
|
||||
.done = text_input_done,
|
||||
};
|
||||
constexpr static wl_keyboard_listener keyboard_listener = {
|
||||
.keymap = keyboard_keymap,
|
||||
.enter = keyboard_enter,
|
||||
|
|
|
|||
Loading…
Reference in a new issue