logo头像

技术引领生活!

Ubuntu触摸板调教

本文于2082天之前发表,文中内容可能已经过时。

本文主要解决笔记本打字时误触的问题,并且在没有鼠标的时候自动识别

解决方案

  1. 安装touchpad-indicator(这个因为好久的项目,貌似在鼠标插拔时有bug)
1
2
3
sudo add-apt-repository ppa:atareao/atareao
sudo apt update
sudo apt install touchpad-indicator

可以设置为开机自启动,当检测到鼠标插入的时候禁用触摸板,或者只是打字的时候禁用就行非常方便(不推荐)

  1. 使用命令行
    1
    2
    sudo rmmod psmouse    这个是禁用的
    sudo modprobe psmouse 这个是启用的
  2. 使用GNOME Shell Extension安装(推荐)

在Ubuntu软件中心里搜索 Touchpad Indicator的扩展,并安装,非常简单易用

下图是我的设置供参考
设置图

编程

作为一个程序员,首先关心的就是能否自己实现,下面分两种系统进行浅析

  1. Linux 系统

    • 命令行:

      1
      2
      3
      4
      5
      xinput --list 获取所有设备列表
      或者cat /proc/bus/input/devices获取所有设备详细信息

      禁用设备:xinput set-prop "id" "Device Enabled" 0
      启用设备:xinput set-prop "10" "Device Enabled" 1

      通过上述命令然后定时获取鼠标的在线情况,然后启动或者禁用触摸板,或者通过事件机制

    • 编程: 大致分为两步

      ①通过netlinksocket

      ②使用udev编写规则

    C语言代码实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/un.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <linux/types.h>
    #include <linux/netlink.h>
    #include <errno.h>
    #include <unistd.h>

    #define UEVENT_BUFFER_SIZE 2048

    static int init_hotplug_sock()
    {
    struct sockaddr_nl snl;
    const int buffer_size = 16 * 1024 * 1024;
    int retval = 0;
    memset(&snl, 0, sizeof(snl));
    snl.nl_family = AF_NETLINK;
    snl.nl_pid = getpid();
    snl.nl_groups = 1;

    int hotplug_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

    if(hotplug_sock == -1)
    {
    printf("error gettting socket %s\n", strerror(errno));
    return -1;
    }

    setsockopt(hotplug_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffer_size, sizeof(buffer_size));

    retval = bind(hotplug_sock, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));

    if(retval < 0)
    {
    printf("bind failed %s\n", strerror(errno));
    close(hotplug_sock);
    hotplug_sock = -1;
    return -1;
    }

    return hotplug_sock;
    }

    int main(int argc, char *argv[])
    {
    printf("Hello Deivce!\n");
    int hotplug_sock = init_hotplug_sock();

    while(1)
    {
    char buf[UEVENT_BUFFER_SIZE * 2] = {0};
    recv(hotplug_sock, &buf, sizeof(buf), 0);
    printf("%s\n", buf);
    }

    return 0;
    }
  2. window系统

    • 通过注册表

    • 通过消息WM_DEVICECHANGE OndeviceChange()实现

支付宝打赏 微信打赏

您的支持是我前行的动力!