转至元数据结尾
转至元数据起始

正在查看旧版本。 查看 当前版本.

与当前比较 恢复该版本 查看页面历史

版本 1 下一步 »

本文记录的是在银河麒麟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应用层。如下图所示。

鼠标模拟双指缩放功能.drawio.png

其中hwc中的代码逻辑是鼠标滚轮模拟双指触摸缩放功能的具体实现,事件处理流程如下图所示。

滚轮事件与触摸事件切换.drawio.png

鼠标模拟双指缩放功能实现完后遇到的问题:

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)事件。

x11_monitor.png

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)事件。如下图所示。

x11全局事件.png

综上两点进一步确认了,不是weston的问题,其他x11client端确实都有收到Ctrl按键up事件,怀疑Xorg server端的问题。

5、排查Xorg端:初步使用gdb调试,发现麒麟桌面的Xorg没有开启debug。下一步只能自行编译xserver项目源码,编译调试版本并安装。具体编译安装步骤已在另外一篇文档单独记录,地址:h. xserver debug版本编译过程说明

经过编译安装后,注销重新登录。开始对Xorg进行gdb调试分析。

0 评论

你还没有登录。你所做的任何更改会将作者标记为匿名用户。 如果你已经拥有帐户,请登录