15 Commits

Author SHA1 Message Date
Maarten van Gompel
ed702f9562 version bump prior to release 2025-08-31 17:40:05 +02:00
Maarten van Gompel
ecc3d5ae1a desktop layout: added cyrillic 2025-08-31 13:48:59 +02:00
Jun Aruga
74667dc2e8 Adjust the deskintl layout set's default font size.
Because the deskintl layout set is for desktop, laptop, and tablet devices with
a larger touchscreen. The default font size can be larger than the mobintl
layout set's default font size.

We created the config.deskintl.h based on config.mobintl.h, which is
for mobile devices. However, the current font "Sans 14" is a bit small in my
environment, Framework Laptop 12 (a 2-in-1 laptop with a 12.2-inch touchscreen).

Signed-off-by: Jun Aruga <jun.aruga@gmail.com>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2025-08-10 14:17:39 +02:00
Jun Aruga
cf60305a61 Update README for layout-specific config.h and deskintl layout set
This commit is to update the README.md for layout-specific config.h
at the commit <49975e78ee437c6fb4a5f6ea3ccf8bc90dc65536>, and
deskintl layout set the commit <90ac0454cda3e376147c49abbb6b2fa0022211f0>.

Signed-off-by: Jun Aruga <jun.aruga@gmail.com>
2025-08-10 00:31:03 +02:00
Maarten van Gompel
915a881111 README: fixed typo in git send-email instructions 2025-08-10 00:29:06 +02:00
Maarten van Gompel
5318ee9256 updated man page
mentioned desktop layout and documented --non-exclusive parameter
2025-08-09 21:56:48 +02:00
Maarten van Gompel
3a44beac1f Added --non-exclusive parameter to skip requesting exclusive zone from compositor
This allows wvkbd to show on top of existing windows, not pushing them
out of the way.

Ref: https://github.com/jjsullivan5196/wvkbd/issues/102
Ref: https://github.com/jjsullivan5196/wvkbd/issues/93
2025-08-09 21:44:01 +02:00
Maarten van Gompel
b3a7e95c69 added SHIFT_SPACE_IS_TAB as compile time parameter
for the mobile layout, we want shift+space to produce tab , which needed
to be implemented in the main code. For the desktop layout, we don't want
this though, a config parameter now handles this at compile time.

Ref: https://github.com/jjsullivan5196/wvkbd/pull/103
2025-08-09 21:19:08 +02:00
Maarten van Gompel
5689b6bd33 Fix landscape appearance bug in multi-monitor setup
In a multi-monitor setup, the keyboard didn't appear correctly since
commit 9cc8931b46 . This affected only
landscape mode and only on multi-monitor setups where wvkbd is launched
on anything but the first output (and perhaps even only in
multi-monitor setups where one is portrait mode and one landscape like
mine, I'm not sure).

In the mentioned commit Willow commented:

> On situation where multiple screens are present, it will eventually need
> a second loop (roundtrip)

It seems that second loop never really made it all the way to drawing.
Adding an explicit drwsurf_attach() unconditionally in
layer_surface_configure fixes this.

I'm not sure if this is the best way but this fixes this bug, and as far
as I know doesn't cause extra redraws/resizes in the normal
single-monitor scenario.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2025-08-09 20:54:28 +02:00
Jun Aruga
90ac0454cd Add deskintl (desktop international) layout set.
Add a layout set aimed at desktop, laptop, and tablet devices with a larger
touchscreen. The layout is the US-International English, adding a compose key.
https://en.wikipedia.org/wiki/QWERTY#US-International

This layout set was created based on the layout set by the user nine7nine
(Jordan Johnston) <https://github.com/nine7nine>.

Note I copied the keymap.mobintl.h into the keymap.deskintl.h, and modified the
keymap.deskintl.h as follows to fix "<" (comma+shift), ">" (period+shift), "?"
(slash+shift) keys.

The following commit changed the key codes in the keymap.h for mobile. I
reverted the change for the keymap.deskintl.h.
9e4cf69137

Below is the difference between the keymap.mobintl.h and keymap.deskintl.h now.

```
$ diff -u keymap.mobintl.h keymap.deskintl.h
...
@@ -1226,9 +1225,9 @@
         key <AB05>               {	[               b,               B, equal ] };\
         key <AB06>               {	[               n,               N, question ] };\
         key <AB07>               {	[               m,               M, exclam ] };\
-        key <AB08>               {	[           comma,      apostrophe, less, U00AB] };\
-        key <AB09>               {	[          period,        question, greater, U00BB] };\
-        key <AB10>               {	[           slash,        greater ] };\
+        key <AB08>               {	[           comma,            less, backslash] };\
+        key <AB09>               {	[          period,         greater, bar ] };\
+        key <AB10>               {	[           slash,        question ] };\
         key <I147>               {  [      exclamdown,   questiondown, exclamdown ] };\
         key <RTSH>               {	[         Shift_R ] };\
         key <KPMU>               {\
...
```

Co-authored-by: Jordan Johnston <johnstonljordan@gmail.com>
Signed-off-by: Jun Aruga <jun.aruga@gmail.com>
2025-08-09 20:52:27 +02:00
Jun Aruga
49975e78ee Support a layout-specific config.h.
* Rename config.def.h to config.mobintl.h.
* config.mobintl.h:
  * Rename the macro config_def_h_INCLUDED to config_h_INCLUDED.
  * Remove a tailing space as a refactoring.
* Makefile: Add config.h to the clean task.

Signed-off-by: Jun Aruga <jun.aruga@gmail.com>
2025-08-09 20:52:27 +02:00
Zach DeCook
b0fd6777fc namespace: change to wvkbd
Hyprland recently added a layerrule to allow certain layers to appear on the lockscreen,
but layers only identify themselves by the namespace.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2025-04-26 23:43:55 +02:00
Willow Barraco
3142271882 Do not expose drwsurf_flip 2025-04-18 07:51:19 +02:00
Willow Barraco
ace77b2aaa Tie the damage tracking to the drawing methods
So that keyboard.c just need to draw things, and stop worring about
damaging.
2025-04-18 07:51:19 +02:00
Willow Barraco
47d27e48d5 gitignore man page 2025-04-18 07:41:27 +02:00
14 changed files with 4036 additions and 33 deletions

2
.gitignore vendored
View File

@@ -6,5 +6,7 @@ include/config.h
.gdb_history
*.log
wvkbd
*.1
config.h
wvkbd-mobintl
wvkbd-deskintl

View File

@@ -29,7 +29,7 @@ OBJECTS = $(SOURCES:.c=.o)
all: ${BIN} ${DOCS}
config.h:
cp config.def.h config.h
cp config.${LAYOUT}.h config.h
proto/%-client-protocol.c: proto/%.xml
wayland-scanner code < $? > $@
@@ -43,7 +43,7 @@ wvkbd-${LAYOUT}: config.h $(OBJECTS) layout.${LAYOUT}.h
$(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS)
clean:
rm -f $(OBJECTS) $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS}
rm -f $(OBJECTS) config.h $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS}
format:
clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS)

View File

@@ -44,18 +44,20 @@ You'll need the following developer packages
You also need [scdoc](https://git.sr.ht/~sircmpwn/scdoc/) to generate the documentation.
Make any customizations you would like in `config.def.h` and run `make`
The default set of layouts is called `mobintl` *(mobile international)*, which groups various layouts aimed at mobile devices
and also attempts to accommodate various international users. The resulting binary is called `wvkbd-mobintl`.
and also attempts to accommodate various international users. Run `make`. The resulting binary is called `wvkbd-mobintl`.
You can, however, define your own layouts by copying and modifying `layout.mobintl.h` and `keymap.mobintl.h`
(replace `mobintl` for something like `yourlayout`). Then make your layout set using `make LAYOUT=yourlayout`, and
the resulting binary will be `wvkbd-yourlayout`
The other set of layouts is called `deskintl` *(desktop international)*, which groups layouts aimed at desktop, laptop, and
tablet devices with a larger touchscreen. The set is US-International English. Run `make LAYOUT=deskintl`. The resulting binary
is called `wvkbd-deskintl`.
You can, however, define your own layouts by copying and modifying `config.mobintl.h`, `layout.mobintl.h` and `keymap.mobintl.h`
(replace `mobintl` for something like `yourlayout`), or `config.deskintl.h`, `layout.deskintl.h` and `keymap.deskintl.h`. Then
make your layout set using `make LAYOUT=yourlayout`, and the resulting binary will be `wvkbd-yourlayout`.
## Usage
Run `wvkbd-mobintl` (or the binary for your custom layout set).
Run `wvkbd-mobintl`, `wvkbd-deskintl` or the binary for your custom layout set.
You can switch between the layouts/layers of the keyboard by pressing the
⌨ key (little keyboard) the bottom-left (press shift to iterate back instead of
@@ -101,7 +103,7 @@ layout by name, even layouts not explicitly added to your layers on startup.
Any contributions are welcome, there are two ways to contribute, the first one is **preferred**:
1. [Sourcehut](https://git.sr.ht/~proycon/wvkbd) - Submit your patches using `git mail` to [~mil/sxmo-devel@lists.sr.ht](mailto:~mil/sxmo-devel@lists.sr.ht), follow [these contribution guidelines](https://sxmo.org/contribute/). Questions can also be asked on Sxmo's [mailing lists](https://sxmo.org/support/).
1. [Sourcehut](https://git.sr.ht/~proycon/wvkbd) - Submit your patches using `git send-email` to [~mil/sxmo-devel@lists.sr.ht](mailto:~mil/sxmo-devel@lists.sr.ht), follow [these contribution guidelines](https://sxmo.org/contribute/). Questions can also be asked on Sxmo's [mailing lists](https://sxmo.org/support/).
2. [Github](https://github.com/jjsullivan5196/wvkbd/) - Submit a pull request or open an issue *(legacy method)*
This project was started by [John Sullivan](https://jsullivan.cc/) and is

45
config.deskintl.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef config_h_INCLUDED
#define config_h_INCLUDED
#define DEFAULT_FONT "Sans 18"
#define DEFAULT_ROUNDING 5
static const int transparency = 255;
struct clr_scheme schemes[] = {
{
/* colors */
.bg = {.bgra = {15, 15, 15, transparency}},
.fg = {.bgra = {45, 45, 45, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
},
{
/* colors */
.bg = {.bgra = {15, 15, 15, transparency}},
.fg = {.bgra = {32, 32, 32, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
}
};
/* layers is an ordered list of layouts, used to cycle through */
static enum layout_id layers[] = {
Full, // First layout is the default layout on startup
Special,
NumLayouts // signals the last item, may not be omitted
};
/* layers is an ordered list of layouts, used to cycle through */
static enum layout_id landscape_layers[] = {
Full, // First layout is the default layout on startup
Special,
NumLayouts // signals the last item, may not be omitted
};
#endif // config_h_INCLUDED

View File

@@ -1,4 +1,4 @@
VERSION = 0.17
VERSION = 0.18
CFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=700
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man

View File

@@ -1,8 +1,9 @@
#ifndef config_def_h_INCLUDED
#define config_def_h_INCLUDED
#ifndef config_h_INCLUDED
#define config_h_INCLUDED
#define DEFAULT_FONT "Sans 14"
#define DEFAULT_ROUNDING 5
#define SHIFT_SPACE_IS_TAB
static const int transparency = 255;
struct clr_scheme schemes[] = {
@@ -31,7 +32,7 @@ struct clr_scheme schemes[] = {
/* layers is an ordered list of layouts, used to cycle through */
static enum layout_id layers[] = {
Full, // First layout is the default layout on startup
Special,
Special,
NumLayouts // signals the last item, may not be omitted
};
@@ -42,4 +43,4 @@ static enum layout_id landscape_layers[] = {
NumLayouts // signals the last item, may not be omitted
};
#endif // config_def_h_INCLUDED
#endif // config_h_INCLUDED

3
drw.c
View File

@@ -131,6 +131,7 @@ drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo);
@@ -159,6 +160,7 @@ drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo);
@@ -175,6 +177,7 @@ drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo);

2
drw.h
View File

@@ -33,10 +33,8 @@ struct drwsurf {
};
struct kbd;
void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s);
void drwsurf_attach(struct drwsurf *ds);
void drwsurf_flip(struct drwsurf *ds);
typedef union {
uint8_t bgra[4];

View File

@@ -301,7 +301,7 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
WL_KEYBOARD_KEY_STATE_RELEASED);
} else {
if ((kb->last_press->code == KEY_SPACE) && (unlatch_shift)) {
if ((kb->shift_space_is_tab) && (kb->last_press->code == KEY_SPACE) && (unlatch_shift)) {
// shift + space is tab
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
WL_KEYBOARD_KEY_STATE_RELEASED);
@@ -404,7 +404,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
}
kb->last_swipe = kb->last_press = k;
kbd_draw_key(kb, k, Press);
if ((k->code == KEY_SPACE) && (kb->mods & Shift)) {
if ((kb->shift_space_is_tab) && (k->code == KEY_SPACE) && (kb->mods & Shift)) {
// shift space is tab
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0);
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
@@ -544,14 +544,6 @@ 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);
drwsurf_damage(
kb->popup_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;
}
}
@@ -584,7 +576,6 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h,
KBD_KEY_BORDER, label, scheme->font_description);
drwsurf_damage(kb->surf, k->x, k->y, k->w, k->h);
if (type == Press || type == Unpress) {
kbd_clear_last_popup(kb);
@@ -601,7 +592,6 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y,
k->w, k->h, KBD_KEY_BORDER, label,
scheme->font_description);
drwsurf_damage(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h);
}
}
@@ -628,7 +618,6 @@ kbd_draw_layout(struct kbd *kb)
}
next_key++;
}
drwsurf_damage(d, 0, 0, kb->w, kb->h);
}
void

View File

@@ -101,6 +101,8 @@ struct kbd {
double scale;
double preferred_scale, preferred_fractional_scale;
bool landscape;
bool shift_space_is_tab;
bool exclusive;
uint8_t mods;
uint8_t compose;
struct key *last_press;
@@ -111,6 +113,7 @@ struct kbd {
size_t last_abc_index; //the layer index of the last alphabetical layout
struct layout *layouts;
struct Output *output; //only used to keep track of landscape flipping, never dereferenced
enum layout_id *layers;
enum layout_id *landscape_layers;

2934
keymap.deskintl.h Normal file

File diff suppressed because it is too large Load Diff

1007
layout.deskintl.h Normal file

File diff suppressed because it is too large Load Diff

20
main.c
View File

@@ -28,7 +28,7 @@
#define countof(x) (sizeof(x) / sizeof(*x))
/* client state */
static const char *namespace = "wlroots";
static const char *namespace = "wvkbd";
static struct wl_display *display;
static struct wl_compositor *compositor;
static struct wl_seat *seat;
@@ -611,7 +611,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
}
if (keyboard.w != w || keyboard.h != h || keyboard.scale != scale ||
hidden) {
keyboard.output != current_output || hidden) {
keyboard.w = w;
keyboard.h = h;
@@ -665,6 +665,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
zwlr_layer_surface_v1_ack_configure(surface, serial);
kbd_resize(&keyboard, layouts, NumLayouts);
drwsurf_attach(&draw_surf);
keyboard.output = current_output;
} else {
zwlr_layer_surface_v1_ack_configure(surface, serial);
}
@@ -716,6 +717,9 @@ usage(char *argv0)
" -l - Comma separated list of layers\n");
fprintf(stderr, " --landscape-layers - Comma separated list of "
"landscape layers\n");
fprintf(stderr, " --non-exclusive - Allow the keyboard to overlap"
" windows. Do not request an exclusive zone from the"
"compositor\n");
}
void
@@ -782,7 +786,9 @@ show()
zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor);
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
if (keyboard.exclusive) {
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
}
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false);
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener,
NULL);
@@ -851,6 +857,7 @@ main(int argc, char **argv)
keyboard.layer_index = 0;
keyboard.preferred_scale = 1;
keyboard.preferred_fractional_scale = 0;
keyboard.exclusive = true;
uint8_t alpha = 0;
bool alpha_defined = false;
@@ -986,6 +993,8 @@ main(int argc, char **argv)
(!strcmp(argv[i], "--list-layers"))) {
list_layers();
exit(0);
} else if ((!strcmp(argv[i], "-non-exclusive")) || (!strcmp(argv[i], "--non-exclusive"))) {
keyboard.exclusive = false;
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[i]);
usage(argv[0]);
@@ -1057,6 +1066,11 @@ main(int argc, char **argv)
if (keyboard.vkbd == NULL) {
die("failed to init virtual keyboard_manager\n");
}
#ifdef SHIFT_SPACE_IS_TAB
keyboard.shift_space_is_tab = true;
#else
keyboard.shift_space_is_tab = false;
#endif
kbd_init(&keyboard, (struct layout *)&layouts, layer_names_list,
landscape_layer_names_list);

View File

@@ -7,6 +7,7 @@ wvkbd - on-screen virtual keyboard for wayland compositors using wlroots
# SYNOPSIS
wvkbd-mobintl [OPTIONS]...
wvkbd-deskintl [OPTIONS]...
*NOTE*: Your binary may have a different suffix depending on which layout you compiled.
@@ -50,6 +51,10 @@ can be patched to add new features.
*--hidden*
Start hidden (send SIGUSR2 to show).
*--non-exclusive*
Allow keyboard to overlap existing windows, do not request an
exclusive zone from the compositor.
*--alpha* _int_
Set alpha value (i.e. transparency) for all colors [0-255]