Uucp@resq.fidonet.org (Uucp) (03/25/91)
From uunet!osf.org!motif-talk-request From: uunet!alfalfa.com!nazgul (Kee Hinckley) To: nazgul@alfalfa.com (Kee Hinckley) Date: Fri, 22 Mar 91 16:41:16 -0500 Cc: larry@sunrise.com (Larry Rogers), motif-talk@osf.org A minor correction to that code (not that it matters out of context, but...) > if (shell && XtParent(shell) && XtIsRealized(XtParent(shell))) { > XtUngrabKeyboard(XtParent(shell), CurrentTime); > if (shell == widget) { > Cardinal numKids, i; > Widget *kids; > > arglist.add(XmNchildren, &kids, XmNnumChildren, &numKids, NULL); > XtGetValues(shell, arglist.args, arglist.clear()); > for (i = 0; i < numKids; ++i) if (XtIsManaged(kids[i])) break; > if (i < numKids) XtSetKeyboardFocus(shell, kids[i]); > } } else XtSetKeyboardFocus(shell, widget); > } -- Uucp - via FidoNet node 1:269/133 UUCP: uunet!resq!Uucp
Uucp@resq.fidonet.org (Uucp) (03/25/91)
From uunet!osf.org!motif-talk-request From: uunet!alfalfa.com!nazgul (Kee Hinckley) To: larry@sunrise.com (Larry Rogers) Date: Fri, 22 Mar 91 16:36:18 -0500 Cc: motif-talk@osf.org > By the way, was it you that asked about the loss of keyboard > focus when using accelerators to bring up dialogs? If it was, > I did some research. It appears to be a timing problem that > occurs more frequently on some systems than others. The > DECstation 3100 we have fails every time you do two accelerators > in a row. The MIPS fails only once in a blue moon. The Sun, > almost never. > > An easy fix that I incorporated into my code was to use > XtUngrabKeyboard directly before displaying any dialog. Note > that I only do this if the pop-up dialog shell's parent widget is > realized and I pass the parent widget as a parameter to the routine. > Because the routine checks for grab conditions before doing > an XUngrabKeyboard, it causes no X errors and because it never > uses the widget, except to get the display/screen info, it isn't > too picky about what widget is used. I'm getting sick and tired of this bug. I don't see it, incidentally on my dialogs, but rather on a main window that I invoke and close using accelerators. It's clearly a focus problem, because whenever it happens I can press Alt-F to bring up the File menu and it will bring up the File menu in the *old* window. In fact, it will even do this if the old window is no longer mapped. Of course this results in an X error when it unmaps it, but fortunately I trap those. I tried what you suggested and indeed it did seem to make things better. (It's hard to tell exactly, since the problem doesn't happen reliably.) However I now get the case where the new window comes up and doesn't visibly have the focus anywhere, but if I start typing I find that I'm in one of the text widgets. *However* it turns out that the translations and accelerators don't work (this is an improvement mind you, typing didn't used to work either). So I poked around and I looked at the change_managed code in Vendor.c and so I added the following code to my manage routine if (shell && XtParent(shell) && XtIsRealized(XtParent(shell))) { XtUngrabKeyboard(XtParent(shell), CurrentTime); if (shell == widget) { Cardinal numKids, i; Widget *kids; arglist.add(XmNchildren, &kids, XmNnumChildren, &numKids, NULL); XtGetValues(shell, arglist.args, arglist.clear()); for (i = 0; i < numKids; ++i) if (XtIsManaged(kids[i])) break; if (i < numKids) XtSetKeyboardFocus(shell, kids[i]); } } I do that after a realize (if it's the first time) and before I map the window. Note the parallels here with the Dialog code we've all been talking about. Vendor shell is doing special stuff in its change_managed routine, even though there are other times when a VendorShell will end up on the screen without going through that code. So. This code in fact seems to work pretty well. I now get the window coming up and it usually has a focus indicator somewhere, and the times that it doesn't, pressing TAB will make one appear. All the translations seem to work all the time too. (Mind you, I've been using this for about half an hour, but the next time I do something it might turn out I'm all wrong and it doesn't work.) So. Why am I still annoyed? Well I take this window *down* on an accelerator too. And doing stuff at window map time isn't going to fix that. I'm going to go off and do a XtUngrabKeyboard when I unmap the window and see what happens there. Maybe that will fix it, but I really hate this kind of stuff - I'm just playing in the dark. Does anyone who *knows* something care to comment? And people really think they can write a virtual toolkit that hides Motif? Drugs! Alfalfa Software, Inc. | Poste: The EMail for Unix nazgul@alfalfa.com | Send Anything... Anywhere 617/646-7703 (voice/fax) | info@alfalfa.com I'm not sure which upsets me more: that people are so unwilling to accept responsibility for their own actions, or that they are so eager to regulate everyone else's. -- Uucp - via FidoNet node 1:269/133 UUCP: uunet!resq!Uucp
gabe@hpcvlx.cv.hp.com (Gabe Begeddov) (03/28/91)
/ hpcvlx:comp.windows.x.motif / Uucp@resq.fidonet.org (Uucp) / 4:56 am Mar 25, 1991 / > An easy fix that I incorporated into my code was to use > XtUngrabKeyboard directly before displaying any dialog. Note > that I only do this if the pop-up dialog shell's parent widget is > realized and I pass the parent widget as a parameter to the routine. > Because the routine checks for grab conditions before doing > an XUngrabKeyboard, it causes no X errors and because it never > uses the widget, except to get the display/screen info, it isn't > too picky about what widget is used. I'm getting sick and tired of this bug. I don't see it, incidentally on my dialogs, but rather on a main window that I invoke and close using accelerators. It's clearly a focus problem, because whenever it happens I can press Alt-F to bring up the File menu and it will bring up the File menu in the *old* window. In fact, it will even do this if the old window is no longer mapped. Of course this results in an X error when it unmaps it, but fortunately I trap those. I think this problem is caused by the inability of the Xt passive grab routines (Xt[Un]Grab[Key,Button]) to always tell when a grab has been released. The Xm menu accelerators are layered on top of the Xt passive grab facility which are in turn layered on top of the server passive grabs (X[Un]Grab[Key,Button]). One of the reasons the Xt wrappers were added was to avoid event processing mishaps when toolkits/apps tried to mix X style event redirection (via grabs and X focus) with Xt style event redirection (via XtSetKeyboardFocus and the modal cascade). Xt keeps enough state around to recoginize when a passive grab has activated by checking incoming press events in a manner similar to the way the server recognizes grabs. The way that Xt recognizes that the grab has gone away is to look at release events and if they match up with a press that has caused a grab then it goes away. Again, similar to the server. Unfortunately, this isn't good enough. There are at least two situations where Xt currently misses grab releases and therefore merrily continues to enforce the grab. In your situation it would cause events to continue to be forwarded to the hierarchy that you had unmapped. The first is when the grab window becomes unviewable (it or one of its ancestors is unmapped). The server will release the grab but Xt would need to do some extra work in order to infer unviewabilility and thereby know that the grab has been released. If the window underneath the window that was released doesn't happen to have release interest expressed on it by this application's connection then the eventual keyrelease won't even be seen by this client ! That is the second problem area. While the server sees all events on all windows :-), the client has to explicitly request events. If the keyrelease were to occur in a window that doesn't have release interest Xt will never see it and will be unable to recognize that the grab has been released. These are both problems with the Xt implementation of passive grabs. One way that we found to avoid this problem is to always specify the menu accelerators and mnenomics as being activated on the release rather than the press. You can even argue that this is more compatable with the way that buttons are activated, i.e. on release. You do this by explicitly specifying the accelerator values as "<KeyUp>MyKey". It looks like the documentation (Label) says you should only use keypress events but the implementation actually uses KeyUp for all mnemonics and works if you use it in your label accelerator resource spec. I think the documentation should be changed. As far as the Xt bugs go, maybe a workaround, or even a real fix will be available for R5. Gabe
nazgul@alfalfa.com (Information Junkie) (04/01/91)
> I think this problem is caused by the inability of the Xt passive grab > routines (Xt[Un]Grab[Key,Button]) to always tell when a grab has been > released. The Xm menu accelerators are layered on top of the Xt passiv ... > this isn't good enough. There are at least two situations where Xt > currently misses grab releases and therefore merrily continues to enforce > the grab. In your situation it would cause events to continue to be forwarded > to the hierarchy that you had unmapped. > > The first is when the grab window becomes unviewable (it or one of its > ancestors is unmapped). The server will release the grab but Xt would Well that pretty much sums up the case where I'm reusing windows. I can't stop doing that (performance would be abysmal) ... > That is the second problem area. While the server sees all events on all > windows :-), the client has to explicitly request events. If the keyrelease > were to occur in a window that doesn't have release interest Xt will > never see it and will be unable to recognize that the grab has been released. This is probably the thing I fixed by doing an explicit unrelease everytime I unmap a window? > These are both problems with the Xt implementation of passive grabs. One > way that we found to avoid this problem is to always specify the menu > accelerators and mnenomics as being activated on the release rather than > the press. You can even argue that this is more compatable with the way I've switched to doing this now. I haven't tested it enough to see if the problem goes away. This still leaves one question in my mind. This explains why the accelerators go to the old window. And it explains why the traversal translations don't work (they're all defined on the down transition - not much I can do about that). What it doesn't explain is why the new window often comes up with no widget showing the keyboard focus indicator. And even with the accelerators work, I can't tab or do anything to make the focus visible. Where'd it go? Alfalfa Software, Inc. | Poste: The EMail for Unix nazgul@alfalfa.com | Send Anything... Anywhere 617/646-7703 (voice/fax) | info@alfalfa.com I'm not sure which upsets me more: that people are so unwilling to accept responsibility for their own actions, or that they are so eager to regulate everyone else's.