本文记录的是在银河麒麟V10(SP1)2303版本环境下,排查并修复Weston应用方式启动OpenFDE,Ctrl按键+鼠标滚轮模拟双指触摸缩放功能无法使用的问题的过程。
原理介绍
Xorg 是麒麟系统显示服务端程序,X.Org Server(简称Xorg)是X服务器的一种实现,它是X Window System(X11)中最常用的服务器。X.Org Server 是开源的,并且广泛用于Linux和UNIX系统上。Xorg进程在收到来自鼠标键盘内核驱动上报的事件后,查找当前的焦点目标应用窗口并将鼠标键盘事件通过XCB库(X协议的c语言绑定)发送给对应的焦点应用。这里OpenFDE是基于weston应用窗口运行,weston窗口作为client端实现了X协议,并将Xorg发送过来的鼠标键盘事件通过wayland协议转发给OpenFDE的显示合成器hwc。hwc再将鼠标滚轮事件转换成双指触摸事件并写入OpenFDE启动时创建的wl_touch_events设备节点,Android的EventHub监听此设备节点,当监听收到触摸事件时,将触摸事件通过framework上报给Android应用层。如下图所示。
其中hwc中的代码逻辑是鼠标滚轮模拟双指触摸缩放功能的具体实现,事件处理流程如下图所示。
鼠标模拟双指缩放功能实现完后遇到的问题:
weston应用方式下键盘Ctrl按键按下时滚动鼠标滚轮会导致自动触发Ctrl按键抬起事件,而我们的双指缩放功能的进入退出依赖了Ctrl按键事件,进而导致操作中会快速进入退出双指缩放功能,无法形成连续触摸滑动的双指捏合动作效果。
排查分析过程:
1、首先对比排查了不启动麒麟桌面,以mutter桌面方式启动OpenFDE,发现鼠标滚轮模拟双指触摸缩放功能是正常的。不会频繁收到Ctrl按键up事件。
2、不启动麒麟桌面,以weston桌面方式启动OpenFDE,发现鼠标滚轮模拟双指触摸缩放功能也是正常的。
综上两点初步判断,应该不是weston的问题,可能是麒麟桌面显示服务器程序Xorg的问题,即Xorg可能发送了额外的Ctrl按键up事件。
3、编写一个简单的x11客户端程序,进行进一步的对比排查定位。
x11_event_monitor.c
#include <X11/Xlib.h> #include <stdio.h> #include <stdlib.h> int main() { Display *display; Window window; XEvent event; int screen; // 打开与X服务器的连接 display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "Cannot open display\n"); exit(1); } screen = DefaultScreen(display); // 创建一个窗口 window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 640, 480, 1, BlackPixel(display, screen), WhitePixel(display, screen)); // 选择感兴趣的事件类型 XSelectInput(display, window, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask); // 显示窗口 XMapWindow(display, window); // 事件循环 while (1) { XNextEvent(display, &event); // 处理暴露事件(窗口需要重新绘制) if (event.type == Expose) { XFillRectangle(display, window, DefaultGC(display, screen), 20, 20, 10, 10); } // 处理键盘按键按下事件 else if (event.type == KeyPress) { printf("Key pressed: %x\n", event.xkey.keycode); } // 处理键盘按键抬起事件 else if (event.type == KeyRelease) { printf("Key released: %x\n", event.xkey.keycode); } // 处理鼠标按键按下事件 else if (event.type == ButtonPress) { printf("Mouse button pressed: %x at (%d, %d)\n", event.xbutton.button, event.xbutton.x, event.xbutton.y); } // 处理鼠标按键抬起事件 else if (event.type == ButtonRelease) { printf("Mouse button released: %x at (%d, %d)\n", event.xbutton.button, event.xbutton.x, event.xbutton.y); } } // 关闭与X服务器的连接 XCloseDisplay(display); return 0; }
编译 gcc -o x11_event_monitor x11_event_monitor.c
运行 ./x11_event_monitor
测试结果如下图,我们发现同样会收到Ctrl按键up(release)事件。
4、使用xrecord,通过 XRecord Extension非侵入式的监听全局事件进行对比测试验证。
可编译的代码在 https://github.com/WHLUG/xrecord-example
下载后,执行下面的命令编译运行测试:
sudo apt install libxcb-util-dev libqt5x11extras5-dev libxtst-dev cmake qt5-default
mkdir build
cd build
qmake ..
make
./xrecord-example
完成以后,会弹出一个Qt窗口,可以实时查看全局鼠标和键盘的事件信息。
测试监听全局事件,发现同样会收到Ctrl按键up(release)事件。如下图所示。
综上两点进一步确认了,不是weston的问题,其他x11client端确实都有收到Ctrl按键up事件,怀疑Xorg server端的问题。
5、排查Xorg端:初步使用gdb调试,发现麒麟桌面的Xorg没有开启debug。下一步只能自行编译xserver项目源码,编译调试版本并安装。具体编译安装步骤已在另外一篇文档单独记录,地址:h. xserver debug版本编译过程说明
经过编译安装后,注销重新登录。开始对Xorg进行gdb调试分析。
0 评论