简体   繁体   English

xcb 窗口管理器丢失所有密钥抓取

[英]xcb window manager loses all key grabs

I have an unrepeatable bug of unknown origin in my single threaded window manager that occurs fairly infrequently (once every 2-3 weeks).我的单线程窗口管理器中有一个来源不明的不可重复的错误,这种错误很少发生(每 2-3 周一次)。 Something happens that causes me to lose keyboard input.发生某些事情导致我丢失键盘输入。 Mouse events are still handled properly so I know the event loop is still running, but the key press event is no longer triggered.鼠标事件仍然被正确处理,所以我知道事件循环仍在运行,但不再触发按键事件。 Actually, the key is no longer grabbed.实际上,钥匙不再被抓住。 When I press XCB_MOD_MASK_4+2 to switch to desktop 2, the 2 will show up in the text editor or terminal that currently has the input focus, instead of being grabbed by the window manager.当我按 XCB_MOD_MASK_4+2 切换到桌面 2 时,2 将显示在当前具有输入焦点的文本编辑器或终端中,而不是被窗口管理器抓取。 I thought maybe it was related to xcb_allow_events, so via IPC I can execute these three tests (from within the window manager, cmd is received from an external process):我想可能与 xcb_allow_events 有关,所以通过 IPC 我可以执行这三个测试(从窗口管理器中,从外部进程接收 cmd):


  if (strcmp(cmd,"test0")==0)
    xcb_allow_events(wm.conn, XCB_ALLOW_ASYNC_KEYBOARD, XCB_CURRENT_TIME);
  else if (strcmp(cmd,"test1")==0)
    xcb_allow_events(wm.conn, XCB_ALLOW_SYNC_KEYBOARD, XCB_CURRENT_TIME);
  else if (strcmp(cmd,"test2")==0)
    keyboard();
void keyboard()
{
  int i,m,k;
  xcb_void_cookie_t     cookie;

  spawn("/usr/bin/xmodmap -e 'keycode 108 = Super_L'");  
  spawn("/usr/bin/xmodmap -e 'remove mod1 = Super_L'");

  for (i=0; i<LENGTH(key_bindings); i++)
  {
    m = key_bindings[i].mod; 
    k = keysc(key_bindings[i].keysym); 
    info("grabbing key: %s (%d), mod: %d",key_bindings[i].keysym,k,m);
    cookie = xcb_grab_key_checked(wm.conn, 0, wm.root, m, k, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
    if (xcb_request_check (wm.conn, cookie))
      error("can't grab key");
  }
}

None of these tests help.这些测试都没有帮助。 I know the keyboard function works properly because it works on window manager startup.我知道键盘功能正常工作,因为它在窗口管理器启动时工作。 Also I can see in the log file that the key grabs in the keyboard function are actually being executed (without error) when prompted via IPC.我还可以在日志文件中看到,当通过 IPC 提示时,键盘功能中的键抓取实际上正在执行(没有错误)。 The current workaround is to send sigterm to the window manager process, and then restart the wm.目前的解决方法是将sigterm发送到窗口管理器进程,然后重启wm。 At that point everything works fine again.此时一切正常。

I'm looking for techniques that might be helpful in tracking down the source of this problem, or in correcting the problem once it occurs (another test).我正在寻找可能有助于追踪此问题根源或在问题发生后纠正问题的技术(另一项测试)。 Unfortunately, since I have no clue of the source of this problem, or what triggers it, I cannot make a simple test case to demonstrate.不幸的是,由于我不知道这个问题的根源,或者是什么触发了它,我无法制作一个简单的测试用例来演示。 BTW I check the log files when this happens, and I don't see any pattern leading up to the problem.顺便说一句,发生这种情况时我会检查日志文件,但我没有看到任何导致问题的模式。 Each function logs an entry on entrance and exit.每个函数在入口和出口记录一个条目。

Update 2021-02-12: I thought a restart would be a good workaround until I found the root cause of this problem. 2021 年 2 月 12 日更新:在找到此问题的根本原因之前,我认为重新启动是一个很好的解决方法。 My restart function contains only one line: execvp(lwm_argv[0], lwm_argv);我的重启函数只包含一行:execvp(lwm_argv[0], lwm_argv); where lwm_argv is the argv provided as an argument to main.其中 lwm_argv 是作为参数提供给 main 的 argv。

I was very surprised to see that this did not alleviate the problem.我很惊讶地看到这并没有缓解问题。 I have to completely kill the old process then launch an new one to alleviate the problem.我必须完全杀死旧进程然后启动一个新进程来缓解问题。 So this problem is PID dependant???所以这个问题是PID相关的??? Further, I'm fairly convinced that this problem is somehow related to the stdout/stderr output of other applications launched from within the window manager using execvp.此外,我相当确信这个问题在某种程度上与使用 execvp 从窗口管理器中启动的其他应用程序的 stdout/stderr 输出有关。 I've stopped launching applications from within the window manager and the problem went away.我已经停止从窗口管理器中启动应用程序,问题就消失了。 Any ideas of how launching other applications (and their output) could be affecting the keygrabs within the window manager would be appreciated.任何有关启动其他应用程序(及其输出)如何影响窗口管理器中的按键抓取的想法都将不胜感激。

You could try using strace or perf trace on the X server to see what it is doing with the key events.您可以尝试在 X 服务器上使用straceperf trace来查看它对关键事件做了什么。 It ought to read them from somewhere in /dev/input and send them as events to connected clients.它应该从/dev/input某个地方读取它们并将它们作为事件发送到连接的客户端。

If it isn't sending you events, then you might need to dig into its internal state, perhaps by building a debug server and connecting to it with GDB, to see why it isn't sending those events.如果它没有向您发送事件,那么您可能需要深入了解其内部状态,也许通过构建调试服务器并使用 GDB 连接到它,以了解它为什么不发送这些事件。

But if it is sending events to your WM then they're getting lost somewhere in the library stack.但是,如果它正在向您的 WM 发送事件,那么它们就会在库堆栈中的某个地方丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM