swc

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

commit 0a3e6590c3d40986becce48f0e35decb9d76ba07
parent 20cad8575a6b608caa15c6d3005a958c2810b974
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue, 15 Jun 2021 15:44:57 -0500

change input method/text input

now that compositor manages the launching and killing of input methods.
the hint and purpose text_input parameters are used to control what
type of input is launched.

Diffstat:
Mlibswc/input_method.c | 67++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mlibswc/input_method.h | 4++++
Mlibswc/text_input.c | 54+++++++++++++++++++++++-------------------------------
Mlibswc/text_input.h | 3+++
4 files changed, 90 insertions(+), 38 deletions(-)

diff --git a/libswc/input_method.c b/libswc/input_method.c @@ -1,3 +1,7 @@ +#include <assert.h> +#include <signal.h> +#include <unistd.h> + #include "internal.h" #include "seat.h" #include "input_method.h" @@ -9,13 +13,14 @@ #include <text-input-unstable-v3-server-protocol.h> #include <wayland-server.h> +static pid_t impid; + static void commit_string(struct wl_client *client, struct wl_resource *resource, const char *text) { struct text_input *ti = text_input_get_enabled(); if (!ti) return; - DEBUG("IM COMMIT_STRING\n"); zwp_text_input_v3_send_commit_string(ti->resource, text); } @@ -26,7 +31,6 @@ set_preedit_string(struct wl_client *client, struct wl_resource *resource, const struct text_input *ti = text_input_get_enabled(); if (!ti) return; - DEBUG("IM PREEDIT\n"); zwp_text_input_v3_send_preedit_string(ti->resource, text, cursor_begin, cursor_end); } @@ -37,7 +41,6 @@ delete_surrounding_text(struct wl_client *client, struct wl_resource *resource, struct text_input *ti = text_input_get_enabled(); if (!ti) return; - DEBUG("IM DELETE\n"); zwp_text_input_v3_send_delete_surrounding_text(ti->resource, before_length, after_length); } @@ -51,12 +54,8 @@ commit(struct wl_client *client, struct wl_resource *resource, uint32_t serial) if (!ti) return; - DEBUG("IM COMMIT: %u, %u\n", im->serial, serial); - -/* if (im->serial != serial) return; -*/ im->serial++; zwp_text_input_v3_send_done(ti->resource, ti->serial); @@ -99,6 +98,59 @@ static const struct zwp_input_method_v2_interface input_method_impl = { .destroy = destroy }; +static char * +input_method_program(uint32_t hint, uint32_t purpose) +{ + switch (purpose) { + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE: + return IM_PROG_PHONE; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL: + return IM_PROG_TERMINAL; + } + + return IM_PROG_DEFAULT; +} + +bool +input_method_launch(uint32_t hint, uint32_t purpose) +{ + pid_t pid; + char *prog = input_method_program(hint, purpose); + switch (pid = fork()) { + case 0: + if (execlp(prog, prog, NULL) == -1) { + ERROR("execlp failed for %s\n", prog); + exit(1); + } + break; + case -1: + return false; + default: + impid = pid; + } + + return true; +} + +void +input_method_kill() +{ + if (impid > 0) + kill(impid, SIGTERM); + + impid = 0; +} + +static void +input_method_init(struct wl_resource *im) +{ + struct text_input_manager *tim = wl_global_get_user_data(swc.text_input_manager); + zwp_input_method_v2_send_activate(im); + assert(tim->enabled); + zwp_input_method_v2_send_content_type(im, tim->enabled->hint, tim->enabled->purpose); + zwp_input_method_v2_send_done(im); +} + void get_input_method(struct wl_client *client, struct wl_resource *manager, struct wl_resource *seat, uint32_t id) { @@ -127,6 +179,7 @@ get_input_method(struct wl_client *client, struct wl_resource *manager, struct w } wl_resource_set_implementation(input_method, &input_method_impl, swc.seat->input_method, &imremove); + input_method_init(input_method); swc.seat->input_method->resource = input_method; } diff --git a/libswc/input_method.h b/libswc/input_method.h @@ -2,6 +2,10 @@ struct input_method { struct wl_resource *resource; uint32_t serial; struct wl_client *client; + pid_t pid; }; struct wl_global *input_method_manager_create(struct wl_display *display); +void input_method_kill(); +bool input_method_launch(uint32_t hint, uint32_t purpose); + diff --git a/libswc/text_input.c b/libswc/text_input.c @@ -1,3 +1,5 @@ +#include <assert.h> + #include "compositor.h" #include "view.h" #include "surface.h" @@ -14,6 +16,7 @@ static void destroy(struct wl_client *client, struct wl_resource *resource) { + input_method_kill(); wl_resource_destroy(resource); } @@ -22,22 +25,14 @@ enable(struct wl_client *client, struct wl_resource *resource) { struct text_input_manager *tim = wl_global_get_user_data(swc.text_input_manager); struct text_input *ti = wl_resource_get_user_data(resource); - struct wl_resource *imresource; if (tim->enabled && client != wl_resource_get_client(tim->enabled->resource)) return; - /* TODO remove */ - if (!swc.seat->input_method) - return; - - imresource = swc.seat->input_method->resource; - if (!imresource) - return; + assert(!swc.seat->input_method); wl_list_remove(&ti->link); tim->enabled = ti; - zwp_input_method_v2_send_activate(swc.seat->input_method->resource); } static void @@ -45,19 +40,15 @@ disable(struct wl_client *client, struct wl_resource *resource) { struct text_input_manager *tim = wl_global_get_user_data(swc.text_input_manager); struct text_input *ti = wl_resource_get_user_data(resource); - struct wl_resource *imresource; - - /* TODO remove */ - if (!swc.seat->input_method) - return; - imresource = swc.seat->input_method->resource; - if (!imresource || ti != tim->enabled) + if (ti != tim->enabled) return; wl_list_insert(&tim->disabled, &ti->link); tim->enabled = NULL; zwp_input_method_v2_send_deactivate(swc.seat->input_method->resource); + + input_method_kill(); } static void @@ -93,16 +84,13 @@ set_text_change_cause(struct wl_client *client, struct wl_resource *resource, ui static void set_content_type(struct wl_client *client, struct wl_resource *resource, uint32_t hint, uint32_t purpose) { - struct wl_resource *imresource; - /* TODO remove */ - if (!swc.seat->input_method) - return; + struct text_input *ti = wl_resource_get_user_data(resource); - imresource = swc.seat->input_method->resource; - if (!imresource) + if (!ti->initialized) { + ti->hint = hint; + ti->purpose = purpose; return; - - zwp_input_method_v2_send_content_type(imresource, hint, purpose); + } } static void @@ -114,20 +102,20 @@ set_cursor_rectangle(struct wl_client *client, struct wl_resource *resource, int static void commit(struct wl_client *client, struct wl_resource *resource) { + struct text_input *ti = wl_resource_get_user_data(resource); struct text_input_manager *tim = wl_global_get_user_data(swc.text_input_manager); - struct wl_resource *imresource; - /* TODO remove */ - if (!swc.seat->input_method) - return; if (tim->enabled) tim->enabled->serial++; - imresource = swc.seat->input_method->resource; - if (!imresource) + if (!ti->initialized) { + input_method_launch(ti->hint, ti->purpose); + ti->initialized = true; + /* get_input_method takes care of send events to the input method on init */ return; + } - zwp_input_method_v2_send_done(imresource); + zwp_input_method_v2_send_done(swc.seat->input_method->resource); } static const struct zwp_text_input_v3_interface text_input_impl = { @@ -149,6 +137,7 @@ ti_remove_resource(struct wl_resource *resource) if (ti == tim->enabled) { tim->enabled = NULL; + input_method_kill(); free(ti); return; } @@ -184,6 +173,9 @@ get_text_input(struct wl_client *client, struct wl_resource *manager, uint32_t i text_input->resource = tiresource; text_input->serial = 0; + text_input->hint = 0; + text_input->purpose = 0; + text_input->initialized = false; wl_list_insert(&tim->disabled, &text_input->link); wl_resource_set_implementation(tiresource, &text_input_impl, text_input, &ti_remove_resource); } diff --git a/libswc/text_input.h b/libswc/text_input.h @@ -4,6 +4,9 @@ struct text_input { struct wl_list link; struct wl_resource *resource; uint32_t serial; + uint32_t hint; + uint32_t purpose; + bool initialized; }; struct text_input_manager {