捏划有方 – linux 触控板多手势操作


linux 的输入设备管理设计

采用 GUI 方式与 Linux 系统进行交流,可以通过多种输入设备,如键盘、鼠标、触摸板(touchpad)、触摸屏((touchscreen)、麦克风、遥控杆等,每种输入设备的输入信号、代表含义均有所不同,对这些输入设备进行管理,首要任务必须将这些输入设备的输入信号转化为系统可以理解并能够处理的信息,再由系统根据信息的含义完成后续的各种任务。Linux 设计了相应的机制,来实现这一流程。

pic-1

Linux 是通过操作系统内核中的输入子系统(input subsystem)管理各个输入设备的。具体来说,通过内核中的具体设备驱动程序管理每一个输入设备,操作系统内核中的设备驱动程序,将输入设备的不同输入信号,转化为系统中的一个个不同的输入事件(input event)。以此同时,在各类原始未经处理的输入事件基础上,内核中设计了一个抽象层次更高的服务,即提供了一个独立于具体硬件的、通用的输入事件接口 – evdev。利用 evdev,对来自各个设备驱动各异的输入事件进行统一归纳,并将这些输入事件传递到用户空间,具体实现形式为使用 /dev/input/ 文件夹中的字符设备文件 event,与输入设备建立映射关系,字符设备文件 event 即代表对应输入设备所产生的输入事件。在用户空间,通过访问 /dev/input/ 文件夹下不同的字符设备文件,即可获取不同输入设备的各类输入事件,再通过特定的软件或库(如 libinput)实现输入设备和事件的处理。

pic-1

linux 输入设备的管理工具

利用内核提供的接口,在用户空间,Linux 提供了一系列工具实现对 GUI 的输入设备的管理任务。

xinput 工具 – 针对设备

xinput 是一个 X 环境输入设备的配置和测试工具 (git repository)。其实现了三个核心功能:
– 显示查看当前 GUI 系统中所有输入设备
– 查询特定输入设备信息
– 对特定输入设备属性进行管理(更改、删除)

几个常用的典型指令如下,

(1) 列出当前 GUI 系统中所有识别且有驱动的输入设备信息

指令格式,

xinput
xinput [ – – ] list
xinput [ – – ] list [ – – short || – – long || – – name – only || – – id – only ]

(2) 查看指定输入设备的属性集合

指令格式,

xinput [ – – ] list-props device

  • device 的值可以 xinput list 中显示的 device id 或 device name

(3) 设定特定输入设备的特定属性信息

指令格式,

xinput [ – – ] set-prop device option settings

  • device 的值可以为 xinput list 中显示的 device id 或 device name
  • option 的值可以为 xinput list-props device 中显示的属性(prop)id 或属性名称
  • settings 的值是 xinput list-props device 中显示的属性(prop)的具体数值

(4) 启用 / 禁用某设备

指令格式,

xinput [ – – ] enable / disable device

或者使用属性设定 set-prop 完成,

xinput [ – – ] set-prop device “Device Enable” 1 / 0

libinput 函数库 – 针对设备和事件

libinput 是一个函数库 (git repository)。其目的是为那些需要提供输入设备事件的进程(display servers),构建一个完整的输入栈(input stack)。

作为一个函数库,libinput 提供了一系列的 API 实现了 “设备探测、输入设备管理、输入设备事件处理” 等核心功能。

其典型特征如下,
– 功能上,libinput 的最大特点是可以支持对事件(input event)的处理,其提供了一个易用的 API,可以接受来自于设备的事件,这一功能 xinput 无法提供
– 调用方式上,libinput 不是由应用程序直接使用,因此,可以将其视为一种设备驱动,而非应用程序库
– 应用范围上,libinput 可用于处理与一个桌面系统交互所使用的所有通用输入设备,也可以通过设置使其适用于限定的输入设备。可处理的输入设备包括,
– TouchPad
– Touchscreen
– Mouse
– Keyboard
– TrackPoints and Pointing Sticks
– Switch (Lid Switch / Tablet Mode Switch)
– Graphics tablets
– 新设备和新功能支持上,libinput 比较“保守”,其主要支持常见的通用输入设备和常见的应用功能,为一些不常用的试验性设备和功能提供支持不是 libinput 的主要任务

display server 是 libinput 的主要服务对象,对 Wayland 的 compositor 和 X Server,libinput 都有特定的支持。

libinput 与 Wayland

libinput 不被 Wayland 的应用程序直接使用,而是作为一个输入栈(input stack)被 compositor 进程调用。

pic-3

在 Wayland 环境中,libinput 无需刻意安装,libiinput 包已经作为使用 Wayland 的图形环境的依赖包被安装好。

libinput 与 X.Org

在 X 环境中,与 Wayland 环境一样,libinput 也不是由 X application 直接调用,而是被 “包裹” 在一个定制化的驱动软件包 — xf86-input-libinput 之中,由 X Server 进程调用,让 libinput 能服务于 X 环境下的输入设备。

pic-1

在 Xorg 中使用 libinput,首先需要安装 xf86-input-libinput 包。libinput 被 “完全” 被封装在 xf86-input-libinput 驱动中,外界感知不到其存在。X Server 按指令要求调用驱动,并不直接与 libinput 沟通,X Client 也不知道 libinput 是否被使用。

如前所述,因为 libinput 设计上可以支持处理一个桌面系统上所有可用输入设备,则封装了 libinput 的 xf86-input-libinput 可以替换 X 系统上其他用于输入的驱动包,即那些以 xf86-input- 为前缀的软件包,如 xf86-input-evdev、xf86-input-synaptics 等。同时,在桌面系统的实际使用中,也可以通过添加配置文件(xorg.conf.d 文件夹中的碎片文件)来限定 libinput 的应用输入设备,如此,可以让 xf86-input-libinput 驱动与其他 X.Org 驱动并存使用,驱动各自管理的输入设备。

具体实现上,libinput 作为 X Server 的组成部分,也是通过配置文件的形式与具体输入设备关联,并供 X Server (Xorg) 调用,其配置文件格式必须总体上符合 X Server 配置文件的规范,同时加入 libinput 库支持的特定特征信息

以下是 libinput 库在 Ubuntu 上的具体实现,

pic-5

其中,xserver-xorg-input-libinput 是由 X.org 的 xf86-input-libinput 驱动模块重新构建、用于 Debian/Ubuntu 的软件包。xserver-xorg-input-libinput 包含一个 libinput_drv.so 的库文件,包含一个配置文件 40-libinput.conf,配置文件的安装路径为 /usr/share/X11/xorg.conf.d/,这个路径也是在 X 环境安装配置文件的默认路径。X Server 的自定义配置文件路径为 /etc/X11/xorg.conf.d/,可以利用自定义路径调整各个配置文件的优先级。

libinput-tools 工具箱

为了更好的调试、分析 libinput 函数库的数据,libinput 还提供了专门的工具箱 — libinput-tools。利用工具箱中的各类工具,可以在不改变当前运行设置的基础上,创建一个独立当前 compositor/X Server 中 libinput 环境的新的 libinput 场景,专门用于调试和分析。

使用 libinput 工具箱需要安装单独的软件包(libinput-tools)。ubuntu 上 libinput-tools 实现如下,

pic-6

libinput-tools 工具箱的典型的指令如下,

(1) 列出当前桌面系统中由 libinput 识别的所有设备

指令格式,

libinput [ – ] list – devices

指令结果会列出输入设备的名称和设备属性,这些属性可以与 xinput list-props 列出的属性找到映射关系。

(2) 调试打印出由 libinput 所识别的所有输入事件

指令格式,

libinput [ – ] debug – events

专门针对输入事件的调试工具。在终端运行指令会进入调试状态,打印出 libinput 看到的所有输入事件信息。如果某些输入事件在该状态未打印出来,则表明其未被 libinput 识别。

输入设备管理典型应用 — Linux 中触摸板的多手势操作的管理

作为典型的输入设备,触控板(TouchPad)已是笔记本电脑的标准配置,且随着技术的不断进步,当前触控板可以支持通过多种方式为系统提供输入,尤其是多手势的触控输入方式(Multi-Touch Gestures),如捏(pinch)、划(swipe)等操作方式,已成为潮流性的输入范式,Mac、Windows 等主流操作系统都提供了对多手势输入的支持,Linux 的桌面环境默认设置对多手势支持有限,但可以通过软件扩展其多手势操作管理的能力。

借助系统的输入设备管理体系,Linux 系统已经可以通过 libinput 函数库获取其支持类型的触控板设备的多手势输入事件,为了让多手势操作对桌面环境产生效果,还需要将手势事件与桌面环境下的具体指令操作建立映射关系,为实现这一目的,产生了多个软件工具,如 libiniput-gesturesFusumaGebaar 等,libinput-gestures 是其中最典型的代表。

libinput-gestures 工具 – 触控板手势操作专属软装备

顾名思义,libinput-gestures 是专门为触控板手势设计的工具。其读取系统 libinput 函数库中的触控板相关的手势事件,并将这些手势事件映射到 libinput-gestures 配置文件(libinput-gestures.conf)中已配置的具体手势上,再通过配置文件将每个已配置的具体手势激活(如利用 xdotool 工具)为一个 shell 指令,最终通过关联的 shell 指令完成 “桌面级/窗口级/应用程序级” 的操作。

libinput-gestures 工具的典型功能如下,

(1) 启动/关闭多手势操作

libinput-gestures 有两种启动形式:desktop application 形式和 systemd service 形式。

具体指令格式,

libinput-gestures-setup desktop || service || start || stop || autostart || autostop || restart || status

libinput-gestures-setup 指令是一个 python 程序,其指令参数可以任意组合,按参数位置顺序执行。

(2) 多手势操作查看、调试工具

具体指令格式,

libinput-gestrues [ – h || – v || – d || – r || – d || – c || – – device ]

libinput-gestures 指令是一个 python 程序,其典型参数含义如下,

  • -l (- – list)

    显示当前桌面环境和 libinput-gestures 的配置信息。

  • -d (- – debug)

    精调试。调试信息有限,只涵盖 3 / 4 指的划动信息和 2 / 3 /4 指的捏收放信息。调试需在多手势操作关闭后(libinput-gestures-setup stop)启动有效。

  • r (- – raw)

    粗调试。本质上调用了 libinput-tools 工具箱的 libinput-debug-events 指令,回显桌面系统所有输入设备的输入事件。调试需在多手势操作关闭后(libinput-gestures-setup stop)启动有效。

libinput-gestures 是 libinput 函数库针对专门的输入设备 — touchpad 管理需求的一种更高层的封装,libinput-gestures 所识别的所有的手势(gestures),都是由底层的 libinput 函数库完成,再传递给 libinput-gestures 使用,libinput-gestures 本身没有独立的手势识别能力。

Linux 桌面环境的多手势操作配置实践

以 Ubuntu 为例,

将当前用户设置为 input 用户组成员,这样当前用户才有权限读取 touchpad 设备输入事件信息,

sudo gpasswd -a $USER input

安装依赖环境软件包,

sudo apt install python3 python3-gi python-gobject libinput-tools xdotool [wmctrl]

源码编译方式安装核心软件 libinput-gestures,

git clone https://github.com/bulletmark/libinput-gestures.git
cd libinput-gestures
sudo make install [sudo ./libinput-gestures-setup install]

修改配置文件 /etc/libinput-gestures.conf,设置手势与指令的映射,

启动运行软件,

libinput-gestrues-setup start autostart

利用 UI 工具简化配置流程

为方便 libinput-gestures 配置的设置,可使用专门的 UI 工具 – gestures

### 安装环境依赖包
sudo apt install meson ninja

### 源码编译方式安装 UI 包 - gestures
git clone https://gitlab.com/cunidev/gestures
cd gestures
meson build --prefix=/usr
ninja -C build
sudo ninja -C build install

libinput-gestures 典型配置

libinput-gestures 提供了绝对的自由度,可以将触控板手势与 shell 指令自由的关联,设置得当,可以实现任何桌面环境中触控板的多手势效果。

一个 KDE 环境的典型配置映射如下,

// workplace 切换
gesture swipe left 4 xdotool key Ctrl+Alt+Left
// workplace 切换
gesture swipe right 4 xdotool key Ctrl+Alt+Right
// 当前 window 窗口最小化 (Next 为 X 环境下的 pagedown 键的符号名称
gesture swipe down 4 xdotool key Super_L+Next
// 列出全部窗口
gesture swipe up 3 xdotool key Ctrl+F10
// 从窗口列出状态恢复
gesture swipe down 3 xdotool key Escape
// 放大 workplace
gesture pinch out 2 xdotool key Super_L+equal
// 缩小 workplace
gesture pinch in 2 xdotool key Super_L+minus

Super_L+equal / Super_L+minusKDE 环境下 Workplace 放缩指令,与触控板上的 2 指捏开/捏紧动作相对应,实现放大 / 缩小的效果。也可映射到 Ctrl + =(+)/- 指令来实现窗口内容区域的局部放大 / 缩小效果。

进行 xdotool 按键配置时,可以使用 xev 指令查看每个键盘按键在 X 环境下的符号名称。

Reference

  1. wikipedia – evdev
  2. man page – evdev
  3. The Linux Input Documentation – evdev
  4. man page – xinput
  5. libinput – freedesktop
  6. libinput – ArchWiki (chinese)
  7. man page – libinput(4)
  8. man page – libinput(1)
  9. Setting up Touchpad Gestures in your Ubuntu Laptop
  10. How to Enable Mac-like Gestures on Ubuntu 20.04
  11. How to Install Libinput-gestures to Enable Multi-Touch Gestures in Ubuntu
  12. https://blog.csdn.net/u011387521/article/details/106685600
  13. Pinch 设置
  14. Multi-Touch Gestures in various DE

发表回复

您的电子邮箱地址不会被公开。