30 Commits

Author SHA1 Message Date
c17c1d3da5 Adapt config to new rebased code 2025-03-11 20:17:12 +01:00
621079c221 Merge branch 'jjsullivan5196:master' into feature/desktop-layout 2025-03-11 20:08:34 +01:00
231623a9c6 Merge branch 'jjsullivan5196:master' into master 2024-09-20 20:13:07 +02:00
fe3257450a version bump 2024-09-01 18:23:07 +02:00
1852b3ab06 Don't forget the obscure AltGr modifier key 2024-09-01 18:21:53 +02:00
9d130e7fd2 Make all modifiers except capslock one shot and redraw keyboard when capslock pressed 2024-09-01 18:21:53 +02:00
2f72b176cb version bump 2024-05-04 19:42:12 +02:00
ba778478e6 added -R parameter to configure rounding 2024-04-15 20:38:02 +02:00
d423720553 Add basic rounding
There's probably a better way of doing this, But this will do for now.

Added basic rounding to buttons.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-04-14 18:18:34 +02:00
e3081fb6e9 fixed malfunctioning theme at random 2024-04-12 22:07:35 +02:00
8106d7606d Check if popup surf configured on callbacks
In some situations, wl_touch_* events come between layer_surface_configure and xdg_popup_surface_configure.
It causes the keyboard to be drawn before the popup surf is configured, leading to "error 3: xdg_surface has never been configured".
This commit fixes this.
2024-03-29 23:16:53 +01:00
02261b5f01 add desktop layout from user nine7nine as independent layout 2024-03-18 17:56:48 +01:00
f1a1865f6b add desktop layout from user nine7nine as independent layout 2024-03-18 17:50:46 +01:00
100764a10c add own darcula theme
add desktop layout from user nine7nine
2024-03-18 17:48:04 +01:00
bb237f5afa Re-open the keyboard on the same output it was
Even if the user is focusing another output while the geometry change.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-03-03 11:33:58 +01:00
b083169ee4 Minimise visual glitches when starting
Most of the time, the first frame have to be rendered without knowing
which output is the current one. It means the first window could have
incorrect dimensions. This cause other program surface to shrink,
then grow back.

Let's try a smoother approach:

If we don't know the current output, we could check if one of them is
landscaped. If this is the case, we start landscaped to minimise the
visual glitch.

Also, the compositor might choose to not send any output geometry
information before the first surface role is assigned (sway master
829c75b9). Meaning after our initial set_size request. So we have to start
landscaped, and eventually flip to horizontal.

Thanks to the patch "Skip the first resize when landscaped while
starting", we do not draw multiple time on the buffer when we switch to vertical
mode.

This should cover most of the cases, and produce a more discrete
start.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-03-01 22:54:34 +01:00
538b48d08d fix fractional scalled buffer missing one pixel
Before 1920*1080 scaled 1.40 was giving a buffer width of 1919 pixels.

The buffer dimensions have to be ceiled here, instead of rounded.

The rest of the dimensions have to stay the same, here 1371x120.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-01-30 18:44:05 +01:00
de3b9a77e4 event loop: exit if the wayland socket disappears
(prevents infinite loop when your compositor crashes)

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-01-30 18:42:17 +01:00
77c6cf4fe6 implemented a stub wl_surface_leave
This fixes "listener function for opcode 1 of wl_surface is NULL" error in wayfire 0.8.0

Ref: https://github.com/jjsullivan5196/wvkbd/issues/52
2023-11-10 20:27:40 +01:00
927918ccc5 version bump 2023-11-04 14:33:44 +01:00
9f8e73b315 fixup: re-add flip_landscape() to wl_surface_enter (needed for landscape detection) 2023-11-04 14:33:30 +01:00
0e17680041 do not refresh on wl_surface_enter
there is no need to do so, because this event is followed by layer_surface_configure.
sway-HEAD(020a572) complains "A configure is scheduled for an uninitialized xdg_surface",
but it works anyway.

fix #50
2023-11-04 14:32:04 +01:00
3cccdab2e8 version bump 2023-11-03 20:53:14 +01:00
2d01b8963b fix hyprland crashes when creating a surface multiple times 2023-11-03 20:47:29 +01:00
c457d697aa optimize output iteration 2023-11-03 20:47:29 +01:00
5471e2ea0e resize keyboard only when entered to different output
the keyboard layout is saved even when hide/show (if output is same).
this is old behavior.
2023-11-03 20:47:29 +01:00
a126945401 handle screen resize and redraw in layer_surface_configure 2023-11-03 20:47:29 +01:00
aa9e8ab7ab avoid using "wl_output" literal 2023-10-29 16:42:19 +01:00
d6439afcb9 Make font selection scheme specific
Add the members font and font_descriptor to struct clr_scheme, so that
it is possible to specify a font for each scheme.

During initialization create the font descriptors for each scheme.

Instead of initially setting the font descriptor when setting up the
buffer, set the font descriptor when drawing the text.

Signed-off-by: Frank Oltmanns <frank@oltmanns.dev>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2023-10-29 13:07:57 +01:00
6e52be343d Add support for multiple schemes
Allow to use more than two color schemes.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2023-10-13 21:20:18 +02:00
12 changed files with 12287 additions and 92 deletions

3
.gitignore vendored
View File

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

View File

@ -51,6 +51,8 @@ You can, however, define your own layouts by copying and modifying `layout.mobin
(replace `mobintl` for something like `yourlayout`). Then make your layout set using `make LAYOUT=yourlayout`, and
the resulting binary will be `wvkbd-yourlayout`
For example there is now a desktop layout that can be built by `make LAYOUT=desktop` and installed afterwards with `make install LAYOUT=desktop`
## Usage
Run `wvkbd-mobintl` (or the binary for your custom layout set).

View File

@ -1,24 +1,31 @@
#ifndef config_def_h_INCLUDED
#define config_def_h_INCLUDED
static const char *default_font = "Sans 14";
#define DEFAULT_FONT "Sans 14"
#define DEFAULT_ROUNDING 5
static const int transparency = 255;
struct clr_scheme scheme = {
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},
};
struct clr_scheme scheme1 = {
.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 */

43
config.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef config_def_h_INCLUDED
#define config_def_h_INCLUDED
#define DEFAULT_FONT "Sans 14"
#define DEFAULT_ROUNDING 5
static const int transparency = 255;
struct clr_scheme schemes[] = {
{
/* colors */
.bg = {.bgra = {54, 42, 40, transparency}},
.fg = {.bgra = {164, 114, 98, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
},
{
/* colors */
.bg = {.bgra = {54, 42, 40, transparency}},
.fg = {.bgra = {90, 71, 68, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
}
};
/* 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[] = {
Landscape, // First layout is the default layout on startup
LandscapeSpecial,
NumLayouts // signals the last item, may not be omitted
};
#endif // config_def_h_INCLUDED

View File

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

55
drw.c
View File

@ -4,6 +4,7 @@
#include "drw.h"
#include "shm_open.h"
#include "math.h"
void
drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s)
@ -15,8 +16,8 @@ drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s)
}
ds->scale = s;
ds->width = w * s;
ds->height = h * s;
ds->width = ceil(w * s);
ds->height = ceil(h * s);
setup_buffer(ds);
}
@ -30,11 +31,14 @@ drwsurf_flip(struct drwsurf *ds)
void
drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label)
uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description)
{
cairo_save(d->cairo);
pango_layout_set_font_description(d->layout, font_description);
cairo_set_source_rgba(
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
@ -67,7 +71,7 @@ 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 over)
uint32_t w, uint32_t h, bool over, int rounding)
{
cairo_save(d->cairo);
@ -77,27 +81,48 @@ drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE);
}
cairo_rectangle(d->cairo, x, y, w, h);
cairo_set_source_rgba(
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
cairo_fill(d->cairo);
if (rounding > 0) {
double radius = rounding / 1.0;
double degrees = M_PI / 180.0;
cairo_restore(d->cairo);
cairo_new_sub_path (d->cairo);
cairo_arc (d->cairo, x + w - radius, y + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc (d->cairo, x + w - radius, y + h - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc (d->cairo, x + radius, y + h - radius, radius, 90 * degrees, 180 * degrees);
cairo_arc (d->cairo, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
cairo_close_path (d->cairo);
cairo_set_source_rgba(
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
cairo_fill (d->cairo);
cairo_set_source_rgba(d->cairo, 0, 0, 0, 0.9);
cairo_set_line_width(d->cairo, 1.0);
cairo_stroke(d->cairo);
}
else {
cairo_rectangle(d->cairo, x, y, w, h);
cairo_set_source_rgba(
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
cairo_fill(d->cairo);
cairo_restore(d->cairo);
}
}
void
drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
uint32_t w, uint32_t h, int rounding)
{
drw_do_rectangle(d, color, x, y, w, h, false);
drw_do_rectangle(d, color, x, y, w, h, false, rounding);
}
void
drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
uint32_t w, uint32_t h, int rounding)
{
drw_do_rectangle(d, color, x, y, w, h, true);
drw_do_rectangle(d, color, x, y, w, h, true, rounding);
}
uint32_t
@ -134,8 +159,6 @@ setup_buffer(struct drwsurf *drwsurf)
cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
cairo_set_antialias(drwsurf->cairo, CAIRO_ANTIALIAS_NONE);
drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
pango_layout_set_font_description(drwsurf->layout,
drwsurf->ctx->font_description);
pango_layout_set_auto_dir(drwsurf->layout, false);
cairo_save(drwsurf->cairo);

10
drw.h
View File

@ -6,7 +6,6 @@
struct drw {
struct wl_shm *shm;
PangoFontDescription *font_description;
};
struct drwsurf {
uint32_t width, height, size;
@ -34,14 +33,15 @@ typedef union {
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);
uint32_t w, uint32_t h, bool fill, int rounding);
void drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
uint32_t w, uint32_t h, int rounding);
void drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
uint32_t w, uint32_t h, int rounding);
void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label);
uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description);
uint32_t setup_buffer(struct drwsurf *drwsurf);

View File

@ -276,13 +276,23 @@ kbd_get_layer_index(struct kbd *kb, struct layout *l)
void
kbd_unpress_key(struct kbd *kb, uint32_t time)
{
bool unlatch_shift = false;
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr;
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = false;
if (kb->last_press) {
unlatch_shift = (kb->mods & Shift) == Shift;
unlatch_ctrl = (kb->mods & Ctrl) == Ctrl;
unlatch_alt = (kb->mods & Alt) == Alt;
unlatch_super = (kb->mods & Super) == Super;
unlatch_altgr = (kb->mods & AltGr) == AltGr;
if (unlatch_shift) {
kb->mods ^= Shift;
if (unlatch_shift) kb->mods ^= Shift;
if (unlatch_ctrl) kb->mods ^= Ctrl;
if (unlatch_alt) kb->mods ^= Alt;
if (unlatch_super) kb->mods ^= Super;
if (unlatch_altgr) kb->mods ^= AltGr;
if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
}
@ -304,7 +314,7 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
if (kb->compose >= 2) {
kb->compose = 0;
kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index);
} else if (unlatch_shift) {
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
kbd_draw_layout(kb);
} else {
kbd_draw_key(kb, kb->last_press, Unpress);
@ -418,7 +428,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
break;
case Mod:
kb->mods ^= k->code;
if (k->code == Shift) {
if ((k->code == Shift) || (k->code == CapsLock)) {
kbd_draw_layout(kb);
} else {
if (kb->mods & k->code) {
@ -551,31 +561,30 @@ kbd_clear_last_popup(struct kbd *kb)
void
kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
{
const char *label = (kb->mods & Shift) ? k->shift_label : k->label;
const char *label = ((kb->mods & Shift)||(kb->mods & CapsLock)) ? 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,
label);
struct clr_scheme *scheme =
(k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1);
struct clr_scheme *scheme = &kb->schemes[k->scheme];
switch (type) {
case None:
case Unpress:
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->fg);
scheme->fg, scheme->rounding);
break;
case Press:
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->high);
scheme->high, scheme->rounding);
break;
case Swipe:
draw_over_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->swipe);
scheme->swipe, scheme->rounding);
break;
}
drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h,
KBD_KEY_BORDER, label);
KBD_KEY_BORDER, label, scheme->font_description);
wl_surface_damage(kb->surf->surf, k->x, k->y, k->w, k->h);
if (type == Press || type == Unpress) {
@ -586,12 +595,13 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
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);
drw_fill_rectangle(kb->popup_surf, scheme->bg, k->x,
kb->last_popup_y, k->w, k->h, scheme->rounding);
draw_inset(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h,
KBD_KEY_BORDER, scheme->high);
KBD_KEY_BORDER, scheme->high, scheme->rounding);
drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y,
k->w, k->h, KBD_KEY_BORDER, label);
k->w, k->h, KBD_KEY_BORDER, label,
scheme->font_description);
wl_surface_damage(kb->popup_surf->surf, k->x, kb->last_popup_y, k->w,
k->h);
}
@ -605,7 +615,7 @@ kbd_draw_layout(struct kbd *kb)
if (kb->debug)
fprintf(stderr, "Draw layout\n");
drw_fill_rectangle(d, kb->scheme.bg, 0, 0, kb->w, kb->h);
drw_fill_rectangle(d, kb->schemes[0].bg, 0, 0, kb->w, kb->h, 0);
while (next_key->type != Last) {
if ((next_key->type == Pad) || (next_key->type == EndRow)) {
@ -647,17 +657,17 @@ kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount)
void
draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color)
uint32_t height, uint32_t border, Color color, int rounding)
{
drw_fill_rectangle(ds, color, x + border, y + border, width - (border * 2),
height - (border * 2));
height - (border * 2), rounding);
}
void
draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color)
uint32_t height, uint32_t border, Color color, int rounding)
{
drw_over_rectangle(ds, color, x + border, y + border, width - (border * 2),
height - (border * 2));
height - (border * 2), rounding);
}
void

View File

@ -54,6 +54,9 @@ struct clr_scheme {
Color high;
Color swipe;
Color text;
char *font;
int rounding;
PangoFontDescription *font_description;
};
struct key {
@ -90,8 +93,7 @@ struct kbd {
bool debug;
struct layout *layout;
struct clr_scheme scheme;
struct clr_scheme scheme1;
struct clr_scheme *schemes;
bool print;
bool print_intersect;
@ -120,9 +122,9 @@ struct kbd {
};
void draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color);
uint32_t height, uint32_t border, Color color, int rounding);
void draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color);
uint32_t height, uint32_t border, Color color, int rounding);
void kbd_init(struct kbd *kb, struct layout *layouts,
char *layer_names_list, char *landscape_layer_names_list);

10245
keymap.desktop.h Normal file

File diff suppressed because it is too large Load Diff

1769
layout.desktop.h Normal file

File diff suppressed because it is too large Load Diff

173
main.c
View File

@ -24,6 +24,9 @@
fprintf(stderr, __VA_ARGS__); \
exit(1)
/* array size */
#define countof(x) (sizeof(x) / sizeof(*x))
/* client state */
static const char *namespace = "wlroots";
static struct wl_display *display;
@ -43,6 +46,7 @@ static struct wp_fractional_scale_v1 *wfs_draw_surf;
static struct wp_fractional_scale_manager_v1 *wfs_mgr;
static struct wp_viewport *draw_surf_viewport, *popup_draw_surf_viewport;
static struct wp_viewporter *viewporter;
static bool popup_xdg_surface_configured;
struct Output {
uint32_t name;
@ -72,6 +76,7 @@ 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;
static int rounding = DEFAULT_ROUNDING;
static bool hidden = false;
/* event handler prototypes */
@ -112,6 +117,8 @@ static void seat_handle_name(void *data, struct wl_seat *wl_seat,
static void wl_surface_enter(void *data, struct wl_surface *wl_surface,
struct wl_output *wl_output);
static void wl_surface_leave(void *data, struct wl_surface *wl_surface,
struct wl_output *wl_output);
static void handle_global(void *data, struct wl_registry *registry,
uint32_t name, const char *interface,
@ -152,6 +159,7 @@ static const struct wl_seat_listener seat_listener = {
static const struct wl_surface_listener surface_listener = {
.enter = wl_surface_enter,
.leave = wl_surface_leave,
};
static const struct wl_registry_listener registry_listener = {
@ -184,6 +192,10 @@ wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
uint32_t time, struct wl_surface *surface, int32_t id,
wl_fixed_t x, wl_fixed_t y)
{
if(!popup_xdg_surface_configured) {
return;
}
struct key *next_key;
uint32_t touch_x, touch_y;
@ -206,6 +218,10 @@ void
wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
uint32_t time, int32_t id)
{
if(!popup_xdg_surface_configured) {
return;
}
kbd_release_key(&keyboard, time);
}
@ -213,6 +229,10 @@ 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)
{
if(!popup_xdg_surface_configured) {
return;
}
uint32_t touch_x, touch_y;
touch_x = wl_fixed_to_int(x);
@ -261,6 +281,10 @@ void
wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
wl_fixed_t surface_x, wl_fixed_t surface_y)
{
if(!popup_xdg_surface_configured) {
return;
}
cur_x = wl_fixed_to_int(surface_x);
cur_y = wl_fixed_to_int(surface_y);
@ -273,6 +297,10 @@ void
wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state)
{
if(!popup_xdg_surface_configured) {
return;
}
struct key *next_key;
cur_press = state == WL_POINTER_BUTTON_STATE_PRESSED;
@ -298,6 +326,10 @@ void
wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
uint32_t axis, wl_fixed_t value)
{
if(!popup_xdg_surface_configured) {
return;
}
kbd_next_layer(&keyboard, NULL, (value >= 0));
drwsurf_flip(keyboard.surf);
}
@ -339,18 +371,27 @@ void
wl_surface_enter(void *data, struct wl_surface *wl_surface,
struct wl_output *wl_output)
{
for (int i = 0; i < WL_OUTPUTS_LIMIT; i += 1) {
struct Output *old_output = current_output;
for (int i = 0; i < wl_outputs_size; i += 1) {
if (wl_outputs[i].data == wl_output) {
current_output = &wl_outputs[i];
break;
}
}
if (current_output == old_output) {
return;
}
keyboard.preferred_scale = current_output->scale;
flip_landscape();
}
void
wl_surface_leave(void *data, struct wl_surface *wl_surface,
struct wl_output *wl_output) {
}
static void
display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
int physical_width, int physical_height, int subpixel,
@ -421,7 +462,7 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
wl_registry_bind(registry, name, &wl_compositor_interface, 3);
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
draw_ctx.shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) {
} else if (strcmp(interface, wl_output_interface.name) == 0) {
if (wl_outputs_size < WL_OUTPUTS_LIMIT) {
struct Output *output = &wl_outputs[wl_outputs_size];
output->data =
@ -457,10 +498,10 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
void
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
{
for (int i = 0; i < WL_OUTPUTS_LIMIT; i += 1) {
for (int i = 0; i < wl_outputs_size; i += 1) {
if (wl_outputs[i].name == name) {
wl_output_destroy(wl_outputs[i].data);
for (; i < WL_OUTPUTS_LIMIT - 1; i += 1) {
for (; i < wl_outputs_size - 1; i += 1) {
wl_outputs[i] = wl_outputs[i + 1];
}
wl_outputs_size -= 1;
@ -474,6 +515,7 @@ xdg_popup_surface_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial)
{
xdg_surface_ack_configure(xdg_surface, serial);
popup_xdg_surface_configured = true;
drwsurf_flip(&popup_draw_surf);
}
@ -485,9 +527,6 @@ 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
@ -516,7 +555,18 @@ static const struct wp_fractional_scale_v1_listener
void
flip_landscape()
{
keyboard.landscape = current_output->w > current_output->h;
bool previous_landscape = keyboard.landscape;
if (current_output) {
keyboard.landscape = current_output->w > current_output->h;
} else if (wl_outputs_size) {
for (int i = 0; i < wl_outputs_size; i += 1) {
if (wl_outputs[i].w > wl_outputs[i].h) {
keyboard.landscape = true;
break;
}
}
}
enum layout_id layer;
if (keyboard.landscape) {
@ -582,6 +632,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
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);
popup_xdg_surface_configured = false;
xdg_surface_add_listener(popup_xdg_surface, &xdg_popup_surface_listener,
NULL);
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL,
@ -599,9 +650,13 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
}
wl_surface_commit(popup_draw_surf.surf);
}
zwlr_layer_surface_v1_ack_configure(surface, serial);
zwlr_layer_surface_v1_ack_configure(surface, serial);
kbd_resize(&keyboard, layouts, NumLayouts);
drwsurf_flip(&draw_surf);
} else {
zwlr_layer_surface_v1_ack_configure(surface, serial);
}
}
void
@ -626,6 +681,7 @@ usage(char *argv0)
" -O - Print intersected keys to standard output\n");
fprintf(stderr, " -H [int] - Height in pixels\n");
fprintf(stderr, " -L [int] - Landscape height in pixels\n");
fprintf(stderr, " -R [int] - Rounding radius in pixels\n");
fprintf(stderr, " --fn [font] - Set font (e.g: DejaVu Sans 20)\n");
fprintf(stderr, " --hidden - Start hidden (send SIGUSR2 to show)\n");
fprintf(
@ -669,6 +725,15 @@ hide()
return;
}
if(wfs_draw_surf) {
wp_fractional_scale_v1_destroy(wfs_draw_surf);
wfs_draw_surf = NULL;
}
if(draw_surf_viewport) {
wp_viewport_destroy(draw_surf_viewport);
draw_surf_viewport = NULL;
}
zwlr_layer_surface_v1_destroy(layer_surface);
wl_surface_destroy(draw_surf.surf);
layer_surface = NULL;
@ -684,6 +749,8 @@ show()
wl_display_sync(display);
flip_landscape();
draw_surf.surf = wl_compositor_create_surface(compositor);
wl_surface_add_listener(draw_surf.surf, &surface_listener, NULL);
if (wfs_mgr && viewporter) {
@ -695,8 +762,12 @@ show()
wp_viewporter_get_viewport(viewporter, draw_surf.surf);
}
struct wl_output *current_output_data = NULL;
if (current_output)
current_output_data = current_output->data;
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
layer_shell, draw_surf.surf, NULL, layer, namespace);
layer_shell, draw_surf.surf, current_output_data, layer, namespace);
zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor);
@ -728,7 +799,7 @@ set_kbd_colors(uint8_t *bgra, char *hex)
// bg, fg, text, high, swipe
int length = strlen(hex);
if (length == 6 || length == 8) {
char subhex[2];
char subhex[3] = { 0 };
memcpy(subhex, hex, 2);
bgra[2] = (int)strtol(subhex, NULL, 16);
memcpy(subhex, hex + 2, 2);
@ -747,9 +818,9 @@ main(int argc, char **argv)
{
/* parse command line arguments */
char *layer_names_list = NULL, *landscape_layer_names_list = NULL;
const char *fc_font_pattern = NULL;
height = normal_height = KBD_PIXEL_HEIGHT;
landscape_height = KBD_PIXEL_LANDSCAPE_HEIGHT;
char *fc_font_pattern = NULL;
height = landscape_height = KBD_PIXEL_LANDSCAPE_HEIGHT;
normal_height = KBD_PIXEL_HEIGHT;
char *tmp;
if ((tmp = getenv("WVKBD_LAYERS")))
@ -764,9 +835,9 @@ main(int argc, char **argv)
/* keyboard settings */
keyboard.layers = (enum layout_id *)&layers;
keyboard.landscape_layers = (enum layout_id *)&landscape_layers;
keyboard.scheme = scheme;
keyboard.schemes = schemes;
keyboard.landscape = true;
keyboard.layer_index = 0;
keyboard.scheme1 = scheme1;
keyboard.preferred_scale = 1;
keyboard.preferred_fractional_scale = 0;
@ -803,7 +874,7 @@ main(int argc, char **argv)
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme.bg.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[0].bg.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-alpha")) ||
(!strcmp(argv[i], "--alpha"))) {
if (i >= argc - 1) {
@ -817,68 +888,74 @@ main(int argc, char **argv)
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme.fg.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[0].fg.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-fg-sp")) ||
(!strcmp(argv[i], "--fg-sp"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme1.fg.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[1].fg.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-press")) ||
(!strcmp(argv[i], "--press"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme.high.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[0].high.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-press-sp")) ||
(!strcmp(argv[i], "--press-sp"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme1.high.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[1].high.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-swipe")) ||
(!strcmp(argv[i], "--swipe"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme.swipe.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[0].swipe.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-swipe-sp")) ||
(!strcmp(argv[i], "--swipe-sp"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme1.swipe.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[1].swipe.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-text")) ||
(!strcmp(argv[i], "--text"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme.text.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[0].text.bgra, argv[++i]);
} else if ((!strcmp(argv[i], "-text-sp")) ||
(!strcmp(argv[i], "--text-sp"))) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
set_kbd_colors(keyboard.scheme1.text.bgra, argv[++i]);
set_kbd_colors(keyboard.schemes[1].text.bgra, argv[++i]);
} else if (!strcmp(argv[i], "-H")) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
height = normal_height = atoi(argv[++i]);
normal_height = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-L")) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
landscape_height = atoi(argv[++i]);
height = landscape_height = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-R")) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
rounding = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-D")) {
keyboard.debug = true;
} else if ((!strcmp(argv[i], "-fn")) || (!strcmp(argv[i], "--fn"))) {
@ -906,16 +983,22 @@ main(int argc, char **argv)
}
if (alpha_defined) {
keyboard.scheme.bg.bgra[3] = alpha;
keyboard.scheme.fg.bgra[3] = alpha;
keyboard.scheme.high.bgra[3] = alpha;
keyboard.scheme1.bg.bgra[3] = alpha;
keyboard.scheme1.fg.bgra[3] = alpha;
keyboard.scheme1.high.bgra[3] = alpha;
keyboard.schemes[0].bg.bgra[3] = alpha;
keyboard.schemes[0].fg.bgra[3] = alpha;
keyboard.schemes[0].high.bgra[3] = alpha;
keyboard.schemes[1].bg.bgra[3] = alpha;
keyboard.schemes[1].fg.bgra[3] = alpha;
keyboard.schemes[1].high.bgra[3] = alpha;
}
if (!fc_font_pattern) {
fc_font_pattern = default_font;
if (fc_font_pattern) {
for (i = 0; i < countof(schemes); i++)
schemes[i].font = fc_font_pattern;
}
if (rounding != DEFAULT_ROUNDING) {
for (i = 0; i < countof(schemes); i++)
schemes[i].rounding = rounding;
}
display = wl_display_connect(NULL);
@ -960,8 +1043,10 @@ main(int argc, char **argv)
kbd_init(&keyboard, (struct layout *)&layouts, layer_names_list,
landscape_layer_names_list);
draw_ctx.font_description =
pango_font_description_from_string(fc_font_pattern);
for (i = 0; i < countof(schemes); i++) {
schemes[i].font_description =
pango_font_description_from_string(schemes[i].font);
}
if (!hidden)
show();
@ -998,6 +1083,12 @@ main(int argc, char **argv)
if (fds[WAYLAND_FD].revents & POLLIN)
wl_display_dispatch(display);
if (fds[WAYLAND_FD].revents & POLLERR) {
die("Exceptional condition on wayland socket.\n");
}
if (fds[WAYLAND_FD].revents & POLLHUP) {
die("Wayland socket has been disconnected.\n");
}
if (fds[SIGNAL_FD].revents & POLLIN) {
struct signalfd_siginfo si;
@ -1015,8 +1106,10 @@ main(int argc, char **argv)
}
}
if (fc_font_pattern != default_font) {
if (fc_font_pattern) {
free((void *)fc_font_pattern);
for (i = 0; i < countof(schemes); i++)
schemes[i].font = NULL;
}
return 0;