[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg-devel
Subject:    Re: [PATCH] Also dump passive grabs on XF86LogGrabInfo
From:       Michael Stapelberg <stapelberg () google ! com>
Date:       2015-10-23 11:31:06
Message-ID: CAH9Oa-bPS3v49uE5sgpdJE_HVN4QOQqxzigSSXyFpf5e5GJ=nQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


I'll send the v2 patch in a second.

On Sun, Oct 18, 2015 at 8:53 PM, Peter Hutterer <peter.hutterer@who-t.net>
wrote:

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

Thanks for clarifying, I've fixed that.


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

Done.


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

Actually, turns out I misunderstood how this works: the next pointer is
used to build up a linked list. Since the code is already iterating over
the list, we don't need to follow the next pointer.


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



-- 
Best regards,
Michael

[Attachment #5 (text/html)]

<div dir="ltr">I'll send the v2 patch in a second.<br><div \
class="gmail_extra"><br><div class="gmail_quote">On Sun, Oct 18, 2015 at 8:53 PM, \
Peter Hutterer <span dir="ltr">&lt;<a href="mailto:peter.hutterer@who-t.net" \
target="_blank">peter.hutterer@who-t.net</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Thu, Oct 15, 2015 at \
09:32:56AM -0700, Michael Stapelberg wrote:<br> &gt; This patch is not entirely \
finished, I've marked the places that need further<br> &gt; attention with TODO. Any \
input on these, and on the patch in general, is<br> &gt; appreciated.<br>
&gt;<br>
&gt; Listing passive grabs is useful for debugging the case where users don't \
know<br> &gt; why a keybinding is not consumed by a particular application (typically \
because<br> &gt; another application is grabbing the binding).<br>
&gt;<br>
&gt; I've tried to be consistent in the messages with other places that dump \
grabs<br> &gt; or clients.<br>
&gt;<br>
&gt; ---<br>
&gt;   dix/window.c                              | 108 \
++++++++++++++++++++++++++++++++++++++++<br> &gt;   hw/xfree86/dixmods/xkbPrivate.c | \
2 +<br> &gt;   include/window.h                        |     1 +<br>
&gt;   3 files changed, 111 insertions(+)<br>
&gt;<br>
&gt; diff --git a/dix/window.c b/dix/window.c<br>
&gt; index d57f320..5e15a72 100644<br>
&gt; --- a/dix/window.c<br>
&gt; +++ b/dix/window.c<br>
&gt; @@ -127,6 +127,7 @@ Equipment Corporation.<br>
&gt;   #include &quot;compint.h&quot;<br>
&gt;   #endif<br>
&gt;   #include &quot;selection.h&quot;<br>
&gt; +#include &quot;inpututils.h&quot;<br>
&gt;<br>
&gt;   #include &quot;privates.h&quot;<br>
&gt;   #include &quot;xace.h&quot;<br>
&gt; @@ -273,6 +274,113 @@ log_window_info(WindowPtr pWin, int depth)<br>
&gt;         ErrorF(&quot;\n&quot;);<br>
&gt;   }<br>
&gt;<br>
&gt; +static void<br>
&gt; +log_grab_info(void *value, XID id, void *cdata)<br>
&gt; +{<br>
&gt; +      GrabPtr pGrab;<br>
&gt; +      int i, j;<br>
&gt; +      pGrab = (GrabPtr)value;<br>
&gt; +<br>
&gt; +      ErrorF(&quot;   grab 0x%lx (%s), type &#39;%s&#39; on window \
0x%lx\n&quot;,<br> &gt; +                 (unsigned long) pGrab-&gt;resource,<br>
&gt; +                 (pGrab-&gt;grabtype == XI2) ? &quot;xi2&quot; :<br>
&gt; +                 ((pGrab-&gt;grabtype == CORE) ? &quot;core&quot; : \
&quot;xi1&quot;),<br> &gt; +                 pGrab-&gt;type == ButtonPress ? \
&quot;ButtonPress&quot; :<br> &gt; +                 // TODO: where do \
DeviceButtonPress and DeviceKeyPress come from?<br> &gt; +                 // They \
are undefined when compiling.<br> &gt; +                 //pGrab-&gt;type == \
DeviceButtonPress ? &quot;DeviceButtonPress&quot; :<br> <br>
</div></div>internally the server uses InternalEvents. depending on which client we \
send<br> the event to, we convert that into a XI2, XI1 or core event. so a grab<br>
that&#39;s grabtype XI2 and type ButtonPress is a DeviceButtonPress grab.<br>
IOW, you can skip the conditions and just check the core types \
here.<br></blockquote><div><br></div><div>Thanks for clarifying, I've fixed \
that.</div><div>  </div><blockquote class="gmail_quote" style="margin:0 0 0 \
.8ex;border-left:1px #ccc solid;padding-left:1ex"> <div><div class="h5"><br>
&gt; +                 pGrab-&gt;type == XI_ButtonPress ? &quot;XI_ButtonPress&quot; \
:<br> &gt; +                 pGrab-&gt;type == KeyPress ? &quot;KeyPress&quot; :<br>
&gt; +                 //pGrab-&gt;type == DeviceKeyPress ? \
&quot;DeviceKeyPress&quot; :<br> &gt; +                 &quot;XI_KeyPress&quot;,<br>
&gt; +                 (unsigned long) pGrab-&gt;window-&gt;<a \
href="http://drawable.id" rel="noreferrer" target="_blank">drawable.id</a>,<br> &gt; \
+                 pGrab-&gt;device-&gt;id);<br> &gt; +      ErrorF(&quot;      detail \
%d (mask %lu), modifiersDetail %d (mask %lu)\n&quot;,<br> &gt; +                 \
pGrab-&gt;detail.exact,<br> &gt; +                 pGrab-&gt;detail.pMask ? (unsigned \
long) *(pGrab-&gt;detail.pMask) : 0,<br> &gt; +                 \
pGrab-&gt;modifiersDetail.exact,<br> &gt; +                 \
pGrab-&gt;modifiersDetail.pMask ?<br> &gt; +                 (unsigned long) \
*(pGrab-&gt;modifiersDetail.pMask) :<br> &gt; +                 (unsigned long) \
0);<br> &gt; +      ErrorF(&quot;      device &#39;%s&#39; (%d), modifierDevice \
&#39;%s&#39; (%d)\n&quot;,<br> &gt; +                 pGrab-&gt;device-&gt;name, \
pGrab-&gt;device-&gt;id,<br> &gt; +                 \
pGrab-&gt;modifierDevice-&gt;name, pGrab-&gt;modifierDevice-&gt;id);<br> &gt; +      \
if (pGrab-&gt;grabtype == CORE) {<br> &gt; +            ErrorF(&quot;      core event \
mask 0x%lx\n&quot;,<br> &gt; +                       (unsigned long) \
pGrab-&gt;eventMask);<br> &gt; +      }<br>
&gt; +      else if (pGrab-&gt;grabtype == XI) {<br>
&gt; +            ErrorF(&quot;      xi1 event mask 0x%lx\n&quot;,<br>
&gt; +                       (unsigned long) pGrab-&gt;eventMask);<br>
&gt; +      }<br>
&gt; +      else if (pGrab-&gt;grabtype == XI2) {<br>
&gt; +            for (i = 0; i &lt; xi2mask_num_masks(pGrab-&gt;xi2mask); i++) {<br>
&gt; +                  const unsigned char *mask;<br>
&gt; +                  int print;<br>
&gt; +<br>
&gt; +                  print = 0;<br>
&gt; +                  for (j = 0; j &lt; XI2MASKSIZE; j++) {<br>
&gt; +                        mask = xi2mask_get_one_mask(pGrab-&gt;xi2mask, i);<br>
&gt; +                        if (mask[j]) {<br>
&gt; +                              print = 1;<br>
&gt; +                              break;<br>
&gt; +                        }<br>
&gt; +                  }<br>
&gt; +                  if (!print)<br>
&gt; +                        continue;<br>
&gt; +                  ErrorF(&quot;         xi2 event mask 0x&quot;);<br>
&gt; +                  for (j = 0; j &lt; xi2mask_mask_size(pGrab-&gt;xi2mask); \
j++)<br> &gt; +                        ErrorF(&quot;%x&quot;, mask[j]);<br>
<br>
</div></div>probably better to print this with spaces between each, it&#39;s hard to \
read<br> otherwise.<br></blockquote><div><br></div><div>Done.</div><div>  \
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"> <span class=""><br>
&gt; +                  ErrorF(&quot;\n&quot;);<br>
&gt; +            }<br>
&gt; +      }<br>
&gt; +      ErrorF(&quot;      owner-events %s, kb %d ptr %d, confine 0x%lx, cursor \
0x%lx\n&quot;,<br> &gt; +                 pGrab-&gt;ownerEvents ? &quot;true&quot; : \
&quot;false&quot;,<br> &gt; +                 pGrab-&gt;keyboardMode, \
pGrab-&gt;pointerMode,<br> &gt; +                 pGrab-&gt;confineTo ? (unsigned \
long) pGrab-&gt;confineTo-&gt;<a href="http://drawable.id" rel="noreferrer" \
target="_blank">drawable.id</a> : 0,<br> &gt; +                 pGrab-&gt;cursor ? \
(unsigned long) pGrab-&gt;cursor-&gt;id : 0);<br> &gt; +<br>
&gt; +      // TODO: dump another grab if there is pGrab-&gt;next<br>
<br>
</span>split the print into a helper function that takes a pGrab as argument, \
then<br> looping through is easy.<br></blockquote><div><br></div><div>Actually, turns \
out I misunderstood how this works: the next pointer is used to build up a linked \
list. Since the code is already iterating over the list, we don't need to follow the \
next pointer.</div><div>  </div><blockquote class="gmail_quote" style="margin:0 0 0 \
.8ex;border-left:1px #ccc solid;padding-left:1ex"> <br>
Cheers,<br>
     Peter<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; +}<br>
&gt; +<br>
&gt; +void<br>
&gt; +PrintPassiveGrabs(void)<br>
&gt; +{<br>
&gt; +      int i;<br>
&gt; +      LocalClientCredRec *lcc;<br>
&gt; +      pid_t clientpid;<br>
&gt; +      const char *cmdname;<br>
&gt; +      const char *cmdargs;<br>
&gt; +<br>
&gt; +      ErrorF(&quot;Printing all currently registered grabs\n&quot;);<br>
&gt; +<br>
&gt; +      for (i = 1; i &lt; currentMaxClients; i++) {<br>
&gt; +            if (!clients[i] || clients[i]-&gt;clientState != \
ClientStateRunning)<br> &gt; +                  continue;<br>
&gt; +<br>
&gt; +            clientpid = GetClientPid(clients[i]);<br>
&gt; +            cmdname = GetClientCmdName(clients[i]);<br>
&gt; +            cmdargs = GetClientCmdArgs(clients[i]);<br>
&gt; +            if ((clientpid &gt; 0) &amp;&amp; (cmdname != NULL)) {<br>
&gt; +                  ErrorF(&quot;   Printing all registered grabs of client pid \
%ld %s %s\n&quot;,<br> &gt; +                             (long) clientpid, cmdname, \
cmdargs ? cmdargs : &quot;&quot;);<br> &gt; +            } else {<br>
&gt; +                  if (GetLocalClientCreds(clients[i], &amp;lcc) == -1) {<br>
&gt; +                        ErrorF(&quot;   GetLocalClientCreds() \
failed\n&quot;);<br> &gt; +                        continue;<br>
&gt; +                  }<br>
&gt; +                  ErrorF(&quot;   Printing all registered grabs of client pid \
%ld uid %ld gid %ld\n&quot;,<br> &gt; +                             \
(lcc-&gt;fieldsSet &amp; LCC_PID_SET) ? (long) lcc-&gt;pid : 0,<br> &gt; +            \
(lcc-&gt;fieldsSet &amp; LCC_UID_SET) ? (long) lcc-&gt;euid : 0,<br> &gt; +           \
(lcc-&gt;fieldsSet &amp; LCC_GID_SET) ? (long) lcc-&gt;egid : 0);<br> &gt; +          \
FreeLocalClientCreds(lcc);<br> &gt; +            }<br>
&gt; +<br>
&gt; +            FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, \
log_grab_info, NULL);<br> &gt; +      }<br>
&gt; +      ErrorF(&quot;End list of registered passive grabs\n&quot;);<br>
&gt; +}<br>
&gt; +<br>
&gt;   void<br>
&gt;   PrintWindowTree(void)<br>
&gt;   {<br>
&gt; diff --git a/hw/xfree86/dixmods/xkbPrivate.c \
b/hw/xfree86/dixmods/xkbPrivate.c<br> &gt; index 574590f..4b9ef33 100644<br>
&gt; --- a/hw/xfree86/dixmods/xkbPrivate.c<br>
&gt; +++ b/hw/xfree86/dixmods/xkbPrivate.c<br>
&gt; @@ -38,6 +38,8 @@ XkbDDXPrivate(DeviceIntPtr dev, KeyCode key, XkbAction \
*act)<br> &gt;                           if (tmp-&gt;deviceGrab.grab)<br>
&gt;                                 PrintDeviceGrabInfo(tmp);<br>
&gt;                     xf86Msg(X_INFO, &quot;End list of active device \
grabs\n&quot;);<br> &gt; +<br>
&gt; +                  PrintPassiveGrabs();<br>
&gt;               }<br>
&gt;               else if (strcasecmp(msgbuf, &quot;ungrab&quot;) == 0)<br>
&gt;                     UngrabAllDevices(FALSE);<br>
&gt; diff --git a/include/window.h b/include/window.h<br>
&gt; index 6daec85..f13ed51 100644<br>
&gt; --- a/include/window.h<br>
&gt; +++ b/include/window.h<br>
&gt; @@ -223,6 +223,7 @@ extern _X_EXPORT RegionPtr CreateClipShape(WindowPtr /* pWin \
*/ );<br> &gt;<br>
&gt;   extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, Bool enable);<br>
&gt;   extern _X_EXPORT void PrintWindowTree(void);<br>
&gt; +extern _X_EXPORT void PrintPassiveGrabs(void);<br>
&gt;<br>
&gt;   extern _X_EXPORT VisualPtr WindowGetVisual(WindowPtr /*pWin*/);<br>
&gt;   #endif                                       /* WINDOW_H */<br>
&gt; --<br>
&gt; 2.1.4<br>
&gt;<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div \
class="gmail_signature">Best regards,<div>Michael</div></div> </div></div>


[Attachment #6 (text/plain)]

_______________________________________________
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

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic