st

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/st
Log | Files | Refs | README | LICENSE

commit fe345ffb3dd6ba9d3383efa8a811cbb870345200
parent 49e9fb5aeba3b7bf5d7beb6733a362e3d8669436
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Sun, 30 May 2021 21:15:09 -0500

input method support

Diffstat:
Mst.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+), 0 deletions(-)

diff --git a/st.c b/st.c @@ -34,6 +34,7 @@ #include "arg.h" #include "xdg-shell-client-protocol.h" +#include "text-input-unstable-v3-client-protocol.h" char *argv0; @@ -98,6 +99,7 @@ char *argv0; /* constants */ #define ISO14755CMD "dmenu -b -p codepoint: </dev/null" +#define BACKSPACE "\b" enum glyph_attribute { ATTR_NULL = 0, @@ -278,6 +280,19 @@ typedef struct { struct wl_data_device *datadev; struct wl_data_offer *seloffer; struct wl_surface *surface; + struct zwp_text_input_v3 *textinput; + struct zwp_text_input_manager_v3 *timanager; + struct { + char commitbuf[4000]; + uint32_t delbefore; + uint32_t delafter; + } tistate; + struct { + char commitbuf[4000]; + uint32_t delbefore; + uint32_t delafter; + } tipending; + uint32_t textserial; struct wl_buffer *buffer; struct xdg_wm_base *wm; struct xdg_surface *xdgsurface; @@ -519,6 +534,12 @@ static void ptrbutton(void *, struct wl_pointer *, uint32_t, uint32_t, uint32_t, uint32_t); static void ptraxis(void *, struct wl_pointer *, uint32_t, uint32_t, wl_fixed_t); +static void tienter(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface); +static void tileave(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface); +static void tipreedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end); +static void ticommit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text); +static void tidelete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t before_length, uint32_t after_length); +static void tidone(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial); static void wmping(void *, struct xdg_wm_base *, uint32_t); static void xdgsurfconfigure(void *, struct xdg_surface *, uint32_t); static void toplevelconfigure(void *, struct xdg_toplevel *, @@ -582,6 +603,14 @@ static struct wl_data_device_listener datadevlistener = static struct wl_data_offer_listener dataofferlistener = { dataofferoffer }; static struct wl_data_source_listener datasrclistener = { datasrctarget, datasrcsend, datasrccancelled }; +static struct zwp_text_input_v3_listener tilistener = { + .enter = tienter, + .leave = tileave, + .preedit_string = tipreedit_string, + .commit_string = ticommit_string, + .delete_surrounding_text = tidelete_surrounding_text, + .done = tidone +}; /* Globals */ static int plumbsel; @@ -3433,6 +3462,8 @@ wlinit(void) die("Display has no data device manager\n"); if (!wl.wm) die("Display has no window manager\n"); + if (!wl.timanager) + die("Display has no text input manager\n"); wl.keyboard = wl_seat_get_keyboard(wl.seat); wl_keyboard_add_listener(wl.keyboard, &kbdlistener, NULL); @@ -3441,6 +3472,8 @@ wlinit(void) wl.datadev = wl_data_device_manager_get_data_device(wl.datadevmanager, wl.seat); wl_data_device_add_listener(wl.datadev, &datadevlistener, NULL); + wl.textinput = zwp_text_input_manager_v3_get_text_input(wl.timanager, wl.seat); + zwp_text_input_v3_add_listener(wl.textinput, &tilistener, NULL); /* font */ if (!FcInit()) @@ -4013,6 +4046,9 @@ regglobal(void *data, struct wl_registry *registry, uint32_t name, } else if (strcmp(interface, "wl_output") == 0) { /* bind to outputs so we can get surface enter events */ wl_registry_bind(registry, name, &wl_output_interface, 2); + } else if (strcmp(interface, "zwp_text_input_manager_v3") == 0) { + /* bind to outputs so we can get surface enter events */ + wl.timanager = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1); } } @@ -4351,6 +4387,63 @@ ptraxis(void * data, struct wl_pointer * pointer, uint32_t time, uint32_t axis, } void +tienter(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + zwp_text_input_v3_enable(text_input); + zwp_text_input_v3_set_content_type(text_input, ZWP_TEXT_INPUT_V3_CONTENT_HINT_LOWERCASE, ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL); + wl.textserial++; + zwp_text_input_v3_commit(text_input); +} + +void +tileave(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + zwp_text_input_v3_disable(text_input); +} + +void +tipreedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end) +{ +} + +void +ticommit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text) +{ + strcpy(wl.tipending.commitbuf, text); +} + +void +tidelete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t before_length, uint32_t after_length) +{ + wl.tipending.delbefore = before_length; + wl.tipending.delafter = after_length; +} + +void +tidone(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial) +{ + wl.tistate.delbefore = wl.tipending.delbefore; + wl.tistate.delafter = wl.tipending.delafter; + strcpy(wl.tistate.commitbuf, wl.tipending.commitbuf); + wl.tipending.delbefore = 0; + wl.tipending.delafter = 0; + wl.tipending.commitbuf[0] = 0; + + if (serial != wl.textserial) + return; + + /* 2. Delete requested surrounding text */ + for (int i = 0; i < wl.tistate.delbefore; i++) + ttysend(BACKSPACE, sizeof(BACKSPACE)); + + /* 3. Insert commit string with the cursor at its end */ + ttysend(wl.tistate.commitbuf, strlen(wl.tistate.commitbuf)); + + zwp_text_input_v3_commit(wl.textinput); + wl.textserial++; +} + +void wmping(void *data, struct xdg_wm_base *wm, uint32_t serial) { xdg_wm_base_pong(wm, serial);