mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2025-03-14 03:12:47 +01:00
Add popup to display pressed keys
This commit is contained in:
parent
b1890848d5
commit
24e354ce9e
12
drw.c
12
drw.c
@ -51,6 +51,18 @@ drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
|
||||
void
|
||||
drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h) {
|
||||
cairo_save(d->cairo);
|
||||
|
||||
cairo_set_operator(d->cairo, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_rectangle(d->cairo, x, y, w, h);
|
||||
cairo_fill(d->cairo);
|
||||
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
|
||||
void
|
||||
drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h, bool over) {
|
||||
|
2
drw.h
2
drw.h
@ -30,6 +30,8 @@ typedef union {
|
||||
uint32_t color;
|
||||
} Color;
|
||||
|
||||
void drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h);
|
||||
void drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h, bool fill);
|
||||
void drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
|
49
keyboard.c
49
keyboard.c
@ -306,6 +306,9 @@ kbd_release_key(struct kbd *kb, uint32_t time) {
|
||||
}
|
||||
|
||||
drwsurf_flip(kb->surf);
|
||||
|
||||
kbd_clear_last_popup(kb);
|
||||
drwsurf_flip(kb->popup_surf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -331,6 +334,9 @@ kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y) {
|
||||
}
|
||||
|
||||
drwsurf_flip(kb->surf);
|
||||
|
||||
kbd_clear_last_popup(kb);
|
||||
drwsurf_flip(kb->popup_surf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -456,6 +462,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) {
|
||||
}
|
||||
|
||||
drwsurf_flip(kb->surf);
|
||||
drwsurf_flip(kb->popup_surf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -497,9 +504,18 @@ kbd_print_key_stdout(struct kbd *kb, struct key *k) {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
kbd_clear_last_popup(struct kbd *kb) {
|
||||
if (kb->last_popup_w && kb->last_popup_h) {
|
||||
drw_do_clear(kb->popup_surf, kb->last_popup_x, kb->last_popup_y, kb->last_popup_w, kb->last_popup_h);
|
||||
wl_surface_damage(kb->popup_surf->surf, kb->last_popup_x, kb->last_popup_y, kb->last_popup_w, kb->last_popup_h);
|
||||
|
||||
kb->last_popup_w = kb->last_popup_h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) {
|
||||
struct drwsurf *d = kb->surf;
|
||||
const char *label = (kb->mods & Shift) ? k->shift_label : k->label;
|
||||
if (kb->debug)
|
||||
fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h,
|
||||
@ -507,20 +523,34 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) {
|
||||
struct clr_scheme *scheme = (k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1);
|
||||
|
||||
switch (type) {
|
||||
case None:
|
||||
case Unpress:
|
||||
draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->fg);
|
||||
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->fg);
|
||||
break;
|
||||
case Press:
|
||||
draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->high);
|
||||
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->high);
|
||||
break;
|
||||
case Swipe:
|
||||
draw_over_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->swipe);
|
||||
draw_over_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->swipe);
|
||||
break;
|
||||
}
|
||||
|
||||
drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, label);
|
||||
drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, label);
|
||||
wl_surface_damage(kb->surf->surf, k->x, k->y, k->w, k->h);
|
||||
|
||||
wl_surface_damage(d->surf, k->x, k->y, k->w, k->h);
|
||||
if (type == Press || type == Unpress) {
|
||||
kbd_clear_last_popup(kb);
|
||||
|
||||
kb->last_popup_x = k->x;
|
||||
kb->last_popup_y = kb->h + k->y - k->h;
|
||||
kb->last_popup_w = k->w;
|
||||
kb->last_popup_h = k->h;
|
||||
|
||||
drw_fill_rectangle(kb->popup_surf, kb->scheme.bg, k->x, kb->last_popup_y, k->w, k->h);
|
||||
draw_inset(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h, KBD_KEY_BORDER, scheme->high);
|
||||
drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y, k->w, k->h, KBD_KEY_BORDER, label);
|
||||
wl_surface_damage(kb->popup_surf->surf, k->x, kb->last_popup_y, k->w, k->h);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -541,7 +571,7 @@ kbd_draw_layout(struct kbd *kb) {
|
||||
(next_key->type == Compose && kb->compose)) {
|
||||
kbd_draw_key(kb, next_key, Press);
|
||||
} else {
|
||||
kbd_draw_key(kb, next_key, Unpress);
|
||||
kbd_draw_key(kb, next_key, None);
|
||||
}
|
||||
next_key++;
|
||||
}
|
||||
@ -550,12 +580,11 @@ kbd_draw_layout(struct kbd *kb) {
|
||||
|
||||
void
|
||||
kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount) {
|
||||
struct drwsurf *d = kb->surf;
|
||||
|
||||
fprintf(stderr, "Resize %dx%d %d, %d layouts\n", kb->w, kb->h, kb->scale,
|
||||
layoutcount);
|
||||
|
||||
drwsurf_resize(d, kb->w, kb->h, kb->scale);
|
||||
drwsurf_resize(kb->surf, kb->w, kb->h, kb->scale);
|
||||
drwsurf_resize(kb->popup_surf, kb->w, kb->h*2, kb->scale);
|
||||
for (int i = 0; i < layoutcount; i++) {
|
||||
if (kb->debug) {
|
||||
if (layouts[i].name)
|
||||
|
@ -42,7 +42,8 @@ enum key_modifier_type {
|
||||
};
|
||||
|
||||
enum key_draw_type {
|
||||
Unpress = 0,
|
||||
None = 0,
|
||||
Unpress,
|
||||
Press,
|
||||
Swipe,
|
||||
};
|
||||
@ -110,7 +111,10 @@ struct kbd {
|
||||
enum layout_id *landscape_layers;
|
||||
|
||||
struct drwsurf *surf;
|
||||
struct drwsurf *popup_surf;
|
||||
struct zwp_virtual_keyboard_v1 *vkbd;
|
||||
|
||||
uint32_t last_popup_x, last_popup_y, last_popup_w, last_popup_h;
|
||||
};
|
||||
|
||||
void draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
|
||||
@ -128,6 +132,7 @@ 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_clear_last_popup(struct kbd *kb);
|
||||
void kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type);
|
||||
void kbd_draw_layout(struct kbd *kb);
|
||||
void kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount);
|
||||
|
82
main.c
82
main.c
@ -1,5 +1,6 @@
|
||||
#include "proto/virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "proto/wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "proto/xdg-shell-client-protocol.h"
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -27,8 +28,13 @@ static struct wl_compositor *compositor;
|
||||
static struct wl_seat *seat;
|
||||
static struct wl_pointer *pointer;
|
||||
static struct wl_touch *touch;
|
||||
static struct wl_region *empty_region;
|
||||
static struct zwlr_layer_shell_v1 *layer_shell;
|
||||
static struct zwlr_layer_surface_v1 *layer_surface;
|
||||
static struct xdg_wm_base *wm_base;
|
||||
static struct xdg_surface *popup_xdg_surface;
|
||||
static struct xdg_popup *popup_xdg_popup;
|
||||
static struct xdg_positioner *popup_xdg_positioner;
|
||||
static struct zwp_virtual_keyboard_manager_v1 *vkbd_mgr;
|
||||
|
||||
struct Output {
|
||||
@ -43,7 +49,7 @@ static int wl_outputs_size;
|
||||
|
||||
/* drawing */
|
||||
static struct drw draw_ctx;
|
||||
static struct drwsurf draw_surf;
|
||||
static struct drwsurf draw_surf, popup_draw_surf;
|
||||
|
||||
/* layer surface parameters */
|
||||
static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
|
||||
@ -348,6 +354,16 @@ static const struct wl_output_listener output_listener = {
|
||||
.done = display_handle_done,
|
||||
.scale = display_handle_scale};
|
||||
|
||||
static void
|
||||
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
||||
{
|
||||
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
||||
.ping = xdg_wm_base_ping,
|
||||
};
|
||||
|
||||
void
|
||||
handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
||||
const char *interface, uint32_t version) {
|
||||
@ -370,6 +386,10 @@ 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);
|
||||
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
|
||||
wm_base =
|
||||
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
||||
xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, NULL);
|
||||
} else if (strcmp(interface,
|
||||
zwp_virtual_keyboard_manager_v1_interface.name) == 0) {
|
||||
vkbd_mgr = wl_registry_bind(registry, name,
|
||||
@ -391,18 +411,64 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_popup_surface_configure(void *data,
|
||||
struct xdg_surface *xdg_surface, uint32_t serial)
|
||||
{
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
drwsurf_flip(&popup_draw_surf);
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener xdg_popup_surface_listener = {
|
||||
.configure = xdg_popup_surface_configure,
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
xdg_popup_configure(void *data,
|
||||
struct xdg_popup *xdg_popup,
|
||||
int32_t x, int32_t y,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
kbd_resize(&keyboard, layouts, NumLayouts);
|
||||
|
||||
drwsurf_flip(&draw_surf);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_popup_done(void *data, struct xdg_popup *xdg_popup) {
|
||||
}
|
||||
|
||||
static const struct xdg_popup_listener xdg_popup_listener = {
|
||||
.configure = xdg_popup_configure,
|
||||
.popup_done = xdg_popup_done,
|
||||
};
|
||||
|
||||
void
|
||||
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
||||
uint32_t serial, uint32_t w, uint32_t h) {
|
||||
if (keyboard.w != w || keyboard.h != h) {
|
||||
keyboard.w = w;
|
||||
keyboard.h = h;
|
||||
kbd_resize(&keyboard, layouts, NumLayouts);
|
||||
|
||||
xdg_positioner_set_size(popup_xdg_positioner, w, h*2);
|
||||
xdg_positioner_set_anchor_rect(popup_xdg_positioner, 0, -h, w, h*2);
|
||||
|
||||
if (popup_xdg_popup) {
|
||||
xdg_popup_destroy(popup_xdg_popup);
|
||||
}
|
||||
|
||||
popup_draw_surf.surf = wl_compositor_create_surface(compositor);
|
||||
wl_surface_set_input_region(popup_draw_surf.surf, empty_region);
|
||||
popup_xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, popup_draw_surf.surf);
|
||||
xdg_surface_add_listener(popup_xdg_surface, &xdg_popup_surface_listener, NULL);
|
||||
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL, popup_xdg_positioner);
|
||||
xdg_popup_add_listener(popup_xdg_popup, &xdg_popup_listener, NULL);
|
||||
zwlr_layer_surface_v1_get_popup(layer_surface, popup_xdg_popup);
|
||||
wl_surface_commit(popup_draw_surf.surf);
|
||||
}
|
||||
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
|
||||
drwsurf_flip(&draw_surf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -689,7 +755,9 @@ main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
draw_surf.ctx = &draw_ctx;
|
||||
popup_draw_surf.ctx = &draw_ctx;
|
||||
keyboard.surf = &draw_surf;
|
||||
keyboard.popup_surf = &popup_draw_surf;
|
||||
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||
@ -704,10 +772,16 @@ main(int argc, char **argv) {
|
||||
if (layer_shell == NULL) {
|
||||
die("layer_shell not available\n");
|
||||
}
|
||||
if (wm_base == NULL) {
|
||||
die("wm_base not available\n");
|
||||
}
|
||||
if (vkbd_mgr == NULL) {
|
||||
die("virtual_keyboard_manager not available\n");
|
||||
}
|
||||
|
||||
empty_region = wl_compositor_create_region(compositor);
|
||||
popup_xdg_positioner = xdg_wm_base_create_positioner(wm_base);
|
||||
|
||||
keyboard.vkbd =
|
||||
zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkbd_mgr, seat);
|
||||
if (keyboard.vkbd == NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user