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
|
|
@ -13,6 +13,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 <string.h>
|
||||
#include <linux/input.h>
|
||||
#include <sys/mman.h>
|
||||
|
|
@ -106,6 +107,11 @@ export namespace Crafter {
|
|||
Event<TouchPoint> onTouchUp;
|
||||
Event<void> onTouchCancel;
|
||||
std::int32_t primaryTouchId = -1;
|
||||
// Text input (zwp_text_input_v3): the input method's composing text
|
||||
// (an empty string clears it) and its deletions around the cursor;
|
||||
// the text it commits arrives as onTextInput, like a key's.
|
||||
Event<const std::string_view> onPreedit;
|
||||
Event<TextDelete> onTextInputDelete;
|
||||
Vector<float, 2> currentMousePos;
|
||||
Vector<float, 2> lastMousePos;
|
||||
Vector<float, 2> mouseDelta;
|
||||
|
|
@ -151,6 +157,11 @@ export namespace Crafter {
|
|||
void StartUpdate();
|
||||
void StopUpdate();
|
||||
void SetTitle(const std::string_view title);
|
||||
// Tells the compositor's input method that a text field has focus
|
||||
// (an on-screen keyboard opens) and where its caret is, in physical
|
||||
// pixels, or that none has. Remembered: it is applied again whenever
|
||||
// the keyboard focus comes back to this window.
|
||||
void SetTextInput(bool active, std::int32_t x = 0, std::int32_t y = 0, std::int32_t width = 0, std::int32_t height = 0, TextInputPurpose purpose = TextInputPurpose::Normal);
|
||||
void Resize(std::uint32_t width, std::uint32_t height);
|
||||
void Render();
|
||||
void Update();
|
||||
|
|
@ -219,6 +230,9 @@ export namespace Crafter {
|
|||
// Needed so `SetCursorImage` can re-issue `wl_pointer_set_cursor`
|
||||
// mid-session (the hotspot only updates when set_cursor is recalled).
|
||||
std::uint32_t lastPointerSerial_ = 0;
|
||||
bool textInputActive_ = false;
|
||||
std::int32_t textInputRect_[4] = { 0, 0, 0, 0 };
|
||||
TextInputPurpose textInputPurpose_ = TextInputPurpose::Normal;
|
||||
|
||||
static void xdg_surface_handle_preferred_scale(void* data, wp_fractional_scale_v1*, std::uint32_t scale);
|
||||
static void wl_surface_frame_done(void *data, wl_callback *cb, uint32_t time);
|
||||
|
|
|
|||
Loading…
Reference in a new issue