wvkbd wayland屏幕键盘 自定义键盘布局,样式修改,(不太好的方法)一键发送组合键
前言
项目地址:https://github.com/jjsullivan5196/wvkbd/tree/master
仅靠经验尝试出的效果,可能不严谨。欢迎指正
文件
主要观察三个文件:
- keyboard.h 查看struct key定义
- layout.mobintl.h 编辑布局
- keyboard.c 实现其它自定义功能
1. struct key定义
观察struct key定义,有助于理解layout中的写法
struct key {
const char *label; // primary label 显示的按键字符 例如 a
const char *shift_label; // secondary label 按住shift后显示的字符 例如 A
const double width; // relative width (1.0) 按键宽度,默认为1.0
const enum key_type type; // 按键类型
const uint32_t
code; /* code: key scancode or modifier name (see 键值
* `/usr/include/linux/input-event-codes.h` for scancode names, and
* `keyboard.h` for modifiers)
* XKB keycodes are +8 */
struct layout *layout; // pointer back to the parent layout that holds this 跳转到其它布局时的指向
// key
const uint32_t code_mod; /* modifier to force when this key is pressed 这个没太理解,感觉可以组合修饰符用 */
uint8_t scheme; // index of the scheme to use 样式,可以观察到键盘上有的键是深色有的是浅色,就是这里设置,默认0为浅灰色,1为深灰色,剩下的需要自己定制见下文
bool reset_mod; /* reset modifiers when clicked 不太理解,没用上 */
// actual coordinates on the surface (pixels), will be computed automatically
// for all keys
uint32_t x, y, w, h;
};
其它说明:
- 关于
width,其实是权重,且仅影响该key的所在行。例如如果在第一行设置E的weith为6,那么E会很长,其它按键会很短。但第二行第三行不受影响
2. 布局
观察layout.mobintl.h文件。
// 第1103行
static struct key keys_landscape[] = {
{"Esc", "Esc", 1.0, Code, KEY_ESC, .scheme = 1},
{"", "", 0.5, Pad, .scheme = 1},
{"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]},
{"w", "W", 1.0, Code, KEY_W, &layouts[ComposeW]},
{"e", "E", 1.0, Code, KEY_E, &layouts[ComposeE]},
{"r", "R", 1.0, Code, KEY_R, &layouts[ComposeR]},
{"t", "T", 1.0, Code, KEY_T, &layouts[ComposeT]},
{"y", "Y", 1.0, Code, KEY_Y, &layouts[ComposeY]},
{"u", "U", 1.0, Code, KEY_U, &layouts[ComposeU]},
{"i", "I", 1.0, Code, KEY_I, &layouts[ComposeI]},
{"o", "O", 1.0, Code, KEY_O, &layouts[ComposeO]},
{"p", "P", 1.0, Code, KEY_P, &layouts[ComposeP]},
{"", "", 0.5, Pad, .scheme = 1},
{"Tab", "Tab", 1.0, Code, KEY_TAB, .scheme = 1},
{"", "", 0.0, EndRow},
//第1120行
这是默认键盘(如果是在横屏电脑上)的第一行。
以{"Esc", "Esc", 1.0, Code, KEY_ESC, .scheme = 1}为例,代表该键为第一行第一个键
- 显示为
Esc - 按下
Shift时,显示Esc - 尺寸为
1.0,类型为Code(此枚举可以在keyboard.h中enum key_type看到) - 键值为
KEY_ESC - 样式索引为
1(也就是深色)
再看{"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]},其中&layouts[Emoji]对应struct key中的layout属性。效果为:按下Cmpose键(Cmp)后再按Q,跳转到emoji键盘
一键发送组合键
这个目前没有发现直接在配置里设置的方法。采用修改源代码的方式,在keyboard.c中。
关键代码如下
使用zwp_virtual_keyboard_v1发送
// 发送TAB 假设time是外部传进来的变量
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB, WL_KEYBOARD_KEY_STATE_PRESSED); // 按下
zwp_virtual_keyboard_v1_key(kb->vkbd, time+1, KEY_TAB, WL_KEYBOARD_KEY_STATE_RELEASED); // 松开
// 发送Ctrl+Space (切换输入法)
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, Ctrl, 0, 0, 0); // 增加Ctrl修饰(Ctrl定义在keyboard.h中)
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_SPACE, WL_KEYBOARD_KEY_STATE_PRESSED); // 按下
zwp_virtual_keyboard_v1_key(kb->vkbd, time+1, KEY_SPACE, WL_KEYBOARD_KEY_STATE_RELEASED); // 松开
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, Ctrl, 0, 0, 0); // 移除修饰
修改实例
// keyboard.c 第368行
void
kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
{
// ...
// 第391行
switch (k->type) {
case Code:
// 可以插入在此处
if (k->Code == KEY_HANGEUL){ // 自定义判断条件,例如特殊键值
// 发送Ctrl+Space (切换输入法)
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, Ctrl, 0, 0, 0); // 增加Ctrl修饰(Ctrl定义在keyboard.h中)
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_SPACE, WL_KEYBOARD_KEY_STATE_PRESSED); // 按下
zwp_virtual_keyboard_v1_key(kb->vkbd, time+1, KEY_SPACE, WL_KEYBOARD_KEY_STATE_RELEASED); // 松开
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, Ctrl, 0, 0, 0); // 移除修饰
kb->last_press=NULL; // 防止在unpress时触发副作用
break;
}
if (k->code_mod) {
if (k->reset_mod) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0,
0);
} else {
zwp_virtual_keyboard_v1_modifiers(
kb->vkbd, kb->mods ^ k->code_mod, 0, 0, 0);
}
} else {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
}
当然也可以在其它地方修改,例如unpress函数
自定义颜色样式
在config.mobintl.h或config.h中,可见schemes定义。
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,
}
};
背景色修改
经测试,背景色仅能通过schemes[0]修改。也就是修改schemes[0]的bg。
新建自定义样式
可以增加一个在数组末尾,也可以直接修改。下面以在末尾添加为例
struct clr_scheme schemes[] = {
{
// 原来的第一个
},
{
// 原来的第二个
},
{
/* colors */
.bg = {.bgra = {15, 15, 15, transparency}}, // 在此处修改背景色无效
.fg = {.bgra = {32, 52, 32, transparency}}, // 按键颜色,此处改为深绿色
.high = {.bgra = {42, 62, 42, transparency}}, // 当按住按键时,高亮颜色,这里改为亮绿色
.swipe = {.bgra = {100, 255, 100, 64}}, // 滑动操作时颜色,没测试不清楚效果
.text = {.bgra = {32, 99, 32, transparency}}, // 字符颜色,此处改为浅绿色
.font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
}
};
然后在布局处应用(layout.mobintl.h)。例如Q键
{"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji]}改为{"q", "Q", 1.0, Code, KEY_Q, &layouts[Emoji], .scheme=2},这里2是我们新增的样式在数组中的索引。
键盘高度
在layout.mobintl.h中
/* constants */
/* how tall the keyboard should be by default (can be overriden) */
#define KBD_PIXEL_HEIGHT 250
/* how tall the keyboard should be by default (can be overriden) */
#define KBD_PIXEL_LANDSCAPE_HEIGHT 120
字体和字号
在config.mobintl.h中
// 第三行
#define DEFAULT_FONT "Sans 14"
浙公网安备 33010602011771号