Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!snorkelwacker!bloom-beacon!UUNET.UU.NET!ken%richs65 From: ken%richs65@UUNET.UU.NET (Ken Marks) Newsgroups: comp.windows.x Subject: (none) Message-ID: <8912222231.AA00959@richs65.> Date: 22 Dec 89 22:31:12 GMT Sender: daemon@athena.mit.edu (Mr Background) Organization: The Internet Lines: 58 The environment: X/NeWS with the OpenLook window manager (click to type mode). The setup: We are using XtSetKeyboardFocus() to direct focus to a "Command Line" widget which is a descentant of a form widget. The problem: Under heavy loads it seems it is possible to type characters and move the pointer into and out of the top level window in such a manner that an infinite recursion developes which causes the client to eventually die with a huge stack. When the keystroke is forwarded from the form widget to the "Command Line" widget, ForwardEvent() is called with widget set to the form widget and client_data set to the "Command Line" widget. It calls DispatchEvent() as follows: DispatchEvent(event, FindFocusWidget((Widget)client_data), mask); FindFocus() creates an ancestor list for the "Command Line" widget. Tracing this list, it determines from the focusList that the top level shell forwards focus to the form and should find that the form widget forwards focus to the "Command Line". But what does happen is this second forward is missing causing FindFocusWidget("Command Line") to return the form widget. DispatchEvent() calls ForwardFocus() again which continues until the process spirals to a miserable death in the far reaches of the stack segment. The problem seemed to be that the GrabRec for the form widget seemed to be missing. After peppering Event.c (from lib/Xt) with printf's and reading the clients dying words, it seemed that a LeaveEvent processed immediately before the keystroke by HandleFocus() was calling RemoveGrab() when it should not have. [Read that: When I did not want it to.] With the addition of some more printf's, I determined that those LeaveEvents had detail fields of NotifyVirtual and NotifyNonlinearVirtual. So I added the following two lines of code to a local copy of Event.c to ignore leaveEvents with that detail. *** Event.c.old Fri Dec 22 14:40:45 1989 --- Event.c Thu Dec 21 16:47:30 1989 *************** *** 1039,1044 **** --- 1039,1046 ---- the focus when the pointer leaves during a grab event->xcrossing.mode != NotifyNormal || */ + event->xcrossing.detail == NotifyVirtual || + event->xcrossing.detail == NotifyNonlinearVirtual || event->xcrossing.detail == NotifyInferior) return; add = (event->type == EnterNotify); break; From initial tests this seems to have fixed the problem and it does not seem to have broken anything else. To make sure, though, that we have not shot ourselves in the foot without realizing it yet, I would appreciate any comments/questions/better-fixes. As we are currently without a news feed, please direct and responses to: uunet!richsun!ken Thanks in advance, Ken Marks