On Thu, Oct 15, 2015 at 09:32:56AM -0700, Michael Stapelberg wrote: > 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" :
internally the server uses InternalEvents. depending on which client we send the event to, we convert that into a XI2, XI1 or core event. so a grab that's grabtype XI2 and type ButtonPress is a DeviceButtonPress grab. IOW, you can skip the conditions and just check the core types here. > + 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]); probably better to print this with spaces between each, it's hard to read otherwise. > + 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 split the print into a helper function that takes a pGrab as argument, then looping through is easy. Cheers, Peter > +} > + > +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 > _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel