[PATCH] Also dump passive grabs on XF86LogGrabInfo

Michael Stapelberg stapelberg at google.com
Thu Oct 15 09:32:56 PDT 2015


This patch is not entirely finished, I’ve marked the places that need further
attention with TODO. Any input on these, and on the patch in general, is
appreciated.

Listing passive grabs is useful for debugging the case where users don’t know
why a keybinding is not consumed by a particular application (typically because
another application is grabbing the binding).

I’ve tried to be consistent in the messages with other places that dump grabs
or clients.

---
 dix/window.c                    | 108 ++++++++++++++++++++++++++++++++++++++++
 hw/xfree86/dixmods/xkbPrivate.c |   2 +
 include/window.h                |   1 +
 3 files changed, 111 insertions(+)

diff --git a/dix/window.c b/dix/window.c
index d57f320..5e15a72 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -127,6 +127,7 @@ Equipment Corporation.
 #include "compint.h"
 #endif
 #include "selection.h"
+#include "inpututils.h"
 
 #include "privates.h"
 #include "xace.h"
@@ -273,6 +274,113 @@ log_window_info(WindowPtr pWin, int depth)
     ErrorF("\n");
 }
 
+static void
+log_grab_info(void *value, XID id, void *cdata)
+{
+    GrabPtr pGrab;
+    int i, j;
+    pGrab = (GrabPtr)value;
+
+    ErrorF("  grab 0x%lx (%s), type '%s' on window 0x%lx\n",
+           (unsigned long) pGrab->resource,
+           (pGrab->grabtype == XI2) ? "xi2" :
+           ((pGrab->grabtype == CORE) ? "core" : "xi1"),
+           pGrab->type == ButtonPress ? "ButtonPress" :
+           // TODO: where do DeviceButtonPress and DeviceKeyPress come from?
+           // They are undefined when compiling.
+           //pGrab->type == DeviceButtonPress ? "DeviceButtonPress" :
+           pGrab->type == XI_ButtonPress ? "XI_ButtonPress" :
+           pGrab->type == KeyPress ? "KeyPress" :
+           //pGrab->type == DeviceKeyPress ? "DeviceKeyPress" :
+           "XI_KeyPress",
+           (unsigned long) pGrab->window->drawable.id,
+           pGrab->device->id);
+    ErrorF("    detail %d (mask %lu), modifiersDetail %d (mask %lu)\n",
+           pGrab->detail.exact,
+           pGrab->detail.pMask ? (unsigned long) *(pGrab->detail.pMask) : 0,
+           pGrab->modifiersDetail.exact,
+           pGrab->modifiersDetail.pMask ?
+           (unsigned long) *(pGrab->modifiersDetail.pMask) :
+           (unsigned long) 0);
+    ErrorF("    device '%s' (%d), modifierDevice '%s' (%d)\n",
+           pGrab->device->name, pGrab->device->id,
+           pGrab->modifierDevice->name, pGrab->modifierDevice->id);
+    if (pGrab->grabtype == CORE) {
+        ErrorF("    core event mask 0x%lx\n",
+               (unsigned long) pGrab->eventMask);
+    }
+    else if (pGrab->grabtype == XI) {
+        ErrorF("    xi1 event mask 0x%lx\n",
+               (unsigned long) pGrab->eventMask);
+    }
+    else if (pGrab->grabtype == XI2) {
+        for (i = 0; i < xi2mask_num_masks(pGrab->xi2mask); i++) {
+            const unsigned char *mask;
+            int print;
+
+            print = 0;
+            for (j = 0; j < XI2MASKSIZE; j++) {
+                mask = xi2mask_get_one_mask(pGrab->xi2mask, i);
+                if (mask[j]) {
+                    print = 1;
+                    break;
+                }
+            }
+            if (!print)
+                continue;
+            ErrorF("      xi2 event mask 0x");
+            for (j = 0; j < xi2mask_mask_size(pGrab->xi2mask); j++)
+                ErrorF("%x", mask[j]);
+            ErrorF("\n");
+        }
+    }
+    ErrorF("    owner-events %s, kb %d ptr %d, confine 0x%lx, cursor 0x%lx\n",
+           pGrab->ownerEvents ? "true" : "false",
+           pGrab->keyboardMode, pGrab->pointerMode,
+           pGrab->confineTo ? (unsigned long) pGrab->confineTo->drawable.id : 0,
+           pGrab->cursor ? (unsigned long) pGrab->cursor->id : 0);
+
+    // TODO: dump another grab if there is pGrab->next
+}
+
+void
+PrintPassiveGrabs(void)
+{
+    int i;
+    LocalClientCredRec *lcc;
+    pid_t clientpid;
+    const char *cmdname;
+    const char *cmdargs;
+
+    ErrorF("Printing all currently registered grabs\n");
+
+    for (i = 1; i < currentMaxClients; i++) {
+        if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+            continue;
+
+        clientpid = GetClientPid(clients[i]);
+        cmdname = GetClientCmdName(clients[i]);
+        cmdargs = GetClientCmdArgs(clients[i]);
+        if ((clientpid > 0) && (cmdname != NULL)) {
+            ErrorF("  Printing all registered grabs of client pid %ld %s %s\n",
+                   (long) clientpid, cmdname, cmdargs ? cmdargs : "");
+        } else {
+            if (GetLocalClientCreds(clients[i], &lcc) == -1) {
+                ErrorF("  GetLocalClientCreds() failed\n");
+                continue;
+            }
+            ErrorF("  Printing all registered grabs of client pid %ld uid %ld gid %ld\n",
+                   (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0,
+                   (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0,
+                   (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0);
+            FreeLocalClientCreds(lcc);
+        }
+
+        FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, log_grab_info, NULL);
+    }
+    ErrorF("End list of registered passive grabs\n");
+}
+
 void
 PrintWindowTree(void)
 {
diff --git a/hw/xfree86/dixmods/xkbPrivate.c b/hw/xfree86/dixmods/xkbPrivate.c
index 574590f..4b9ef33 100644
--- a/hw/xfree86/dixmods/xkbPrivate.c
+++ b/hw/xfree86/dixmods/xkbPrivate.c
@@ -38,6 +38,8 @@ XkbDDXPrivate(DeviceIntPtr dev, KeyCode key, XkbAction *act)
                 if (tmp->deviceGrab.grab)
                     PrintDeviceGrabInfo(tmp);
             xf86Msg(X_INFO, "End list of active device grabs\n");
+
+            PrintPassiveGrabs();
         }
         else if (strcasecmp(msgbuf, "ungrab") == 0)
             UngrabAllDevices(FALSE);
diff --git a/include/window.h b/include/window.h
index 6daec85..f13ed51 100644
--- a/include/window.h
+++ b/include/window.h
@@ -223,6 +223,7 @@ extern _X_EXPORT RegionPtr CreateClipShape(WindowPtr /* pWin */ );
 
 extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, Bool enable);
 extern _X_EXPORT void PrintWindowTree(void);
+extern _X_EXPORT void PrintPassiveGrabs(void);
 
 extern _X_EXPORT VisualPtr WindowGetVisual(WindowPtr /*pWin*/);
 #endif                          /* WINDOW_H */
-- 
2.1.4



More information about the xorg-devel mailing list