commit 2de12a90e4989f040754c2279c1fadae6f8a48f9
parent c541c7dbd611d2dbd5bc722e495a3582c3aee9f8
Author: Zach DeCook <zachdecook@librem.one>
Date: Thu, 2 Dec 2021 11:03:41 -0500
output: add -O flag to output overlapped keys
the use-case for this is simple 'swipe'-typing:
another program can take the output, guess the word which is being typed, and type the rest of the word
Diffstat:
4 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
@@ -66,7 +66,12 @@ Wvkbd has an output mode `-o` that will echo its output to standard output. This
audio/haptic feedback, a feature explicitly out of scope for wvkbd. To achieve this, simply pipe wvkbd's output through the external tool
[clickclack](https://git.sr.ht/~proycon/clickclack):
-`$ wvkbd-mobileintl -l simple,special,emoji -o | clickclack -V -f keypress.wav`
+`$ wvkbd-mobintl -l simple,special,emoji -o | clickclack -V -f keypress.wav`
+
+Another output mode, `-O` will let the keyboard output keys which are swiped over. It can be used by an external program, such as [swipeGuess](https://git.sr.ht/~earboxer/swipeGuess) to get swipe-typing support.
+
+`$ wvkbd-mobintl -O | swipeGuess.sh words.txt | completelyTypeWord.sh`
+
## Contribute
@@ -80,6 +85,7 @@ possible.
## Related projects
* [clickclack](https://git.sr.ht/~proycon/clickclack) - Audio/haptic feedback (standalone)
+* [swipeGuess](https://git.sr.ht/~earboxer/swipeGuess) - Word-completion for swipe-typing
* [Sxmo](https://sxmo.org) - A hackable mobile interface environment for Linux phones that adopted wvkbd as its keyboard
* [svkbd](https://tools.suckless.org/x/svkbd/) - A similar project as wvkbd but for X11 rather than Wayland
* [squeekboard](https://gitlab.gnome.org/World/Phosh/squeekboard) - The virtual keyboard developed for the Librem5 (used
diff --git a/keyboard.c b/keyboard.c
@@ -189,6 +189,31 @@ kbd_unpress_key(struct kbd *kb, uint32_t time) {
}
}
+void kbd_release_key(struct kbd *kb, uint32_t time) {
+ kbd_unpress_key(kb, time);
+ if (kb->print_intersect && kb->last_swipe) {
+ printf("\n");
+ // Important so autocompleted words get typed in time
+ fflush(stdout);
+ kb->last_swipe = NULL;
+ }
+}
+
+void kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y) {
+ // Output intersecting keys
+ // (for external 'swiping'-based accelerators).
+ if (kb->print_intersect) {
+ struct key *intersect_key;
+ intersect_key = kbd_get_key(kb, x, y);
+ if (intersect_key &&
+ (! kb->last_swipe || intersect_key->label != kb->last_swipe->label)) {
+ kbd_print_key_stdout(kb, intersect_key);
+ kb->last_swipe = intersect_key;
+ }
+ }
+ kbd_unpress_key(kb, time);
+}
+
void
kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
if ((kb->compose == 1) && (k->type != Compose) && (k->type != Mod) &&
@@ -212,11 +237,11 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
} else {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
}
- kb->last_press = k;
+ kb->last_swipe = kb->last_press = k;
kbd_draw_key(kb, k, true);
zwp_virtual_keyboard_v1_key(kb->vkbd, time, kb->last_press->code,
WL_KEYBOARD_KEY_STATE_PRESSED);
- if (kb->print)
+ if (kb->print || kb->print_intersect)
kbd_print_key_stdout(kb, k);
if (kb->compose) {
if (kb->debug)
@@ -271,7 +296,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
break;
case Copy:
// copy code as unicode chr by setting a temporary keymap
- kb->last_press = k;
+ kb->last_swipe = kb->last_press = k;
kbd_draw_key(kb, k, true);
if (kb->debug)
fprintf(stderr, "pressing copy key\n");
@@ -279,7 +304,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
WL_KEYBOARD_KEY_STATE_PRESSED);
- if (kb->print)
+ if (kb->print || kb->print_intersect)
kbd_print_key_stdout(kb, k);
break;
default:
diff --git a/keyboard.h b/keyboard.h
@@ -85,11 +85,13 @@ struct kbd {
struct clr_scheme scheme1;
bool print;
+ bool print_intersect;
uint32_t w, h, s;
bool landscape;
uint8_t mods;
uint8_t compose;
struct key *last_press;
+ struct key *last_swipe;
struct layout *prevlayout;
size_t layer_index;
@@ -108,6 +110,8 @@ void kbd_init(struct kbd *kb, struct layout *layouts, char *layer_names_list);
void kbd_init_layout(struct layout *l, uint32_t width, uint32_t height);
struct key *kbd_get_key(struct kbd *kb, uint32_t x, uint32_t y);
void kbd_unpress_key(struct kbd *kb, uint32_t time);
+void kbd_release_key(struct kbd *kb, uint32_t time);
+void kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y);
void kbd_press_key(struct kbd *kb, struct key *k, uint32_t time);
void kbd_print_key_stdout(struct kbd *kb, struct key *k);
void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed);
diff --git a/main.c b/main.c
@@ -42,6 +42,7 @@ static uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
/* application state */
static bool run_display = true;
static int cur_x = -1, cur_y = -1;
+static bool cur_press = false;
static struct kbd keyboard;
static uint32_t height, normal_height, landscape_height;
@@ -159,13 +160,18 @@ wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
void
wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
uint32_t time, int32_t id) {
- kbd_unpress_key(&keyboard, time);
+ kbd_release_key(&keyboard, time);
}
void
wl_touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time,
int32_t id, wl_fixed_t x, wl_fixed_t y) {
- kbd_unpress_key(&keyboard, time);
+ uint32_t touch_x, touch_y;
+
+ touch_x = wl_fixed_to_int(x);
+ touch_y = wl_fixed_to_int(y);
+
+ kbd_motion_key(&keyboard, time, touch_x, touch_y);
}
void
@@ -199,18 +205,24 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
cur_x = wl_fixed_to_int(surface_x);
cur_y = wl_fixed_to_int(surface_y);
- kbd_unpress_key(&keyboard, time);
+ if (cur_press) {
+ kbd_motion_key(&keyboard, time, cur_x, cur_y);
+ }
}
void
wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state) {
struct key *next_key;
- bool press = state == WL_POINTER_BUTTON_STATE_PRESSED;
+ cur_press = state == WL_POINTER_BUTTON_STATE_PRESSED;
- kbd_unpress_key(&keyboard, time);
+ if (cur_press) {
+ kbd_unpress_key(&keyboard, time);
+ } else {
+ kbd_release_key(&keyboard, time);
+ }
- if (press && cur_x >= 0 && cur_y >= 0) {
+ if (cur_press && cur_x >= 0 && cur_y >= 0) {
next_key = kbd_get_key(&keyboard, cur_x, cur_y);
if (next_key) {
kbd_press_key(&keyboard, next_key, time);
@@ -335,7 +347,8 @@ usage(char *argv0) {
argv0);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -D - Enable debug\n");
- fprintf(stderr, " -o - Print press keys to standard output\n");
+ fprintf(stderr, " -o - Print pressed keys to standard output\n");
+ fprintf(stderr, " -O - Print intersected keys to standard output\n");
fprintf(stderr, " -l - Comma separated list of layers\n");
fprintf(stderr, " -H [int] - Height in pixels\n");
fprintf(stderr, " -L [int] - Landscape height in pixels\n");
@@ -445,6 +458,8 @@ main(int argc, char **argv) {
fc_font_pattern = estrdup(argv[++i]);
} else if (!strcmp(argv[i], "-o")) {
keyboard.print = true;
+ } else if (!strcmp(argv[i], "-O")) {
+ keyboard.print_intersect = true;
} else if ((!strcmp(argv[i], "-hidden")) || (!strcmp(argv[i], "--hidden"))) {
starthidden = true;
} else {