xcb window manager loses all key grabs

201 views Asked by At

I have an unrepeatable bug of unknown origin in my single threaded window manager that occurs fairly infrequently (once every 2-3 weeks). 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. 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):


  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. The current workaround is to send sigterm to the window manager process, and then restart the 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. My restart function contains only one line: execvp(lwm_argv[0], lwm_argv); where lwm_argv is the argv provided as an argument to main.

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??? 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. 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.

1

There are 1 answers

2
Zan Lynx On

You could try using strace or perf trace on the X server to see what it is doing with the key events. It ought to read them from somewhere in /dev/input and send them as events to connected clients.

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.

But if it is sending events to your WM then they're getting lost somewhere in the library stack.