• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

卢晓春的博客

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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"

posted on 2026-01-12 14:10  卢晓春  阅读(28)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3