suggestion picker: a persistent layer to complement virtual keyboards like wvkbd
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 113 |
1 files changed, 68 insertions, 45 deletions
@@ -4,6 +4,7 @@ #include <stdlib.h> #include <string.h> #include <sys/mman.h> +#include <sys/signalfd.h> #include <unistd.h> #include <wayland-client.h> #include <wchar.h> @@ -246,7 +247,8 @@ display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, physical_height = tmp; } bool landscape = physical_width > physical_height; - if (landscape == keyboard.landscape) return; + if (landscape == keyboard.landscape) + return; keyboard.landscape = landscape; if (keyboard.landscape) { height = landscape_height; @@ -296,7 +298,6 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name, } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); - } } @@ -340,25 +341,26 @@ usage(char *argv0) { void hide(int sigint) { - if(keyboard.debug) fprintf(stderr, "hiding keyboard\n"); - signal(SIGUSR1, hide); + if (keyboard.debug) + fprintf(stderr, "hiding keyboard\n"); if (!layer_surface) { + if (keyboard.debug) + fprintf(stderr, "can't hide nothing\n"); return; } - zwlr_layer_surface_v1_destroy(layer_surface); wl_surface_destroy(draw_surf.surf); layer_surface = NULL; hidden = true; - // dispatch to make it disappear - wl_display_dispatch(display); } void show(int sigint) { - if(keyboard.debug) fprintf(stderr, "showing keyboard\n"); - signal(SIGUSR2, show); + if (keyboard.debug) + fprintf(stderr, "showing keyboard\n"); if (layer_surface) { + if (keyboard.debug) + fprintf(stderr, "already shown\n"); return; } @@ -376,16 +378,12 @@ show(int sigint) { zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, NULL); wl_surface_commit(draw_surf.surf); - - wl_display_roundtrip(display); - drwsurf_flip(&draw_surf); - // Dispatch so that bar appears (and can take events). - wl_display_dispatch(display); } -void toggle_visibility(int sigint) { - if(keyboard.debug) fprintf(stderr, "toggling visibility\n"); - signal(SIGRTMIN, toggle_visibility); +void +toggle_visibility(int sigint) { + if (keyboard.debug) + fprintf(stderr, "toggling visibility\n"); if (hidden) { show(sigint); } else { @@ -402,19 +400,19 @@ handle_input(FILE *fd, struct key *sugg, struct kbd *kb) { int i; struct key *key = sugg; char *l = line; - for (i = 0; l[i+1]; i++) { + for (i = 0; l[i + 1]; i++) { if (l[i] == '\t') { free(key->label); - key->label = strndup(l,i); + key->label = strndup(l, i); l += i + 1; i = 0; key++; } else if (l[i] == '\n') { break; } - } + } free(key->label); - key->label = strndup(l,i); + key->label = strndup(l, i); key++; free(key->label); key->label = NULL; @@ -508,36 +506,61 @@ main(int argc, char **argv) { if (!hidden) { show(0); - } else { - signal(SIGUSR2, show); } - signal(SIGUSR1, hide); - signal(SIGPIPE, pipewarn); - signal(SIGRTMIN, toggle_visibility); - // We need a more complicated event loop than wayland's default. - struct pollfd fds[2]; - fds[0].fd = STDIN_FILENO; - fds[0].events = POLLIN; - fds[1].fd = wl_display_get_fd(display); - fds[1].events = POLLIN; + struct pollfd fds[3]; + int WAYLAND_FD = 0; + int SIGNAL_FD = 1; + int STDIN_FD = 2; + fds[WAYLAND_FD].events = POLLIN; + fds[SIGNAL_FD].events = POLLIN; + fds[STDIN_FD].events = POLLIN; + + fds[WAYLAND_FD].fd = wl_display_get_fd(display); + if (fds[WAYLAND_FD].fd == -1) { + die("Failed to get wayland_fd: %d\n", errno); + } + + sigset_t signal_mask; + sigemptyset(&signal_mask); + sigaddset(&signal_mask, SIGUSR1); + sigaddset(&signal_mask, SIGUSR2); + sigaddset(&signal_mask, SIGRTMIN); + sigaddset(&signal_mask, SIGPIPE); + if (sigprocmask(SIG_BLOCK, &signal_mask, NULL) == -1) { + die("Failed to disable handled signals: %d\n", errno); + } + fds[SIGNAL_FD].fd = signalfd(-1, &signal_mask, 0); + if (fds[SIGNAL_FD].fd == -1) { + die("Failed to get signalfd: %d\n", errno); + } + + fds[STDIN_FD].fd = STDIN_FILENO; + while (run_display) { - while(layer_surface && poll(fds, 2, -1) != -1) { - if (fds[0].revents & POLLIN) { - handle_input(stdin, keyboard.suggs, &keyboard); - } else if(fds[1].revents & POLLIN) { - //error check? - wl_display_dispatch(display); - } - wl_display_flush(display); + wl_display_flush(display); + poll(fds, 3, -1); + if (fds[STDIN_FD].revents & POLLIN) { + handle_input(stdin, keyboard.suggs, &keyboard); } - if (layer_surface){ - wl_display_roundtrip(display); + if (fds[WAYLAND_FD].revents & POLLIN) { + wl_display_dispatch(display); } - while (run_display && !layer_surface) { - // Hidden - sleep(1); + + if (fds[SIGNAL_FD].revents & POLLIN) { + struct signalfd_siginfo si; + + if (read(fds[SIGNAL_FD].fd, &si, sizeof(si)) != sizeof(si)) + fprintf(stderr, "Signal read error: %d", errno); + else if (si.ssi_signo == SIGUSR1) + hide(0); + else if (si.ssi_signo == SIGUSR2) + show(0); + else if (si.ssi_signo == SIGRTMIN) + toggle_visibility(0); + else if (si.ssi_signo == SIGPIPE) + pipewarn(0); } } |