Avoid processing events belonging to a previous ewin for a client window.

This hopefully puts an end to various menu related segvs that have been causing
trouble since 1.0.3.

SVN revision: 54048
This commit is contained in:
Kim Woelders 2010-10-30 18:41:22 +00:00
parent 2493319624
commit c45c753584
2 changed files with 42 additions and 3 deletions

View File

@ -237,6 +237,8 @@ EwinManage(EWin * ewin)
if (ewin->state.docked)
ewin->inh_wm.b.border = 1;
ewin->serial = NextRequest(disp);
frame = EoGetWin(ewin);
if (!frame)
{
@ -2291,11 +2293,41 @@ ActionsCheck(const char *which, EWin * ewin, XEvent * ev)
return ActionclassEvent(ac, ev, ewin);
}
static EWin *
_EwinEventEwinCheck(const char *txt, XEvent * ev, EWin * ewin)
{
if ((int)(ev->xany.serial - ewin->serial) < 0)
{
Eprintf("%s: %#lx: Ignore obsolete event %d\n", txt,
ev->xany.window, ev->type);
return NULL;
}
ewin->serial = ev->xany.serial;
return ewin;
}
static EWin *
_EwinEventEwinFind(XEvent * ev, Window xwin)
{
EWin *ewin;
ewin = EwinFindByClient(xwin);
if (!ewin)
return ewin;
return _EwinEventEwinCheck("root", ev, ewin);
}
static void
EwinHandleEventsToplevel(Win win __UNUSED__, XEvent * ev, void *prm)
{
EWin *ewin = (EWin *) prm;
if (!_EwinEventEwinCheck("frm", ev, ewin))
return;
switch (ev->type)
{
case ButtonPress:
@ -2325,6 +2357,9 @@ EwinHandleEventsContainer(Win win __UNUSED__, XEvent * ev, void *prm)
EWin *ewin = (EWin *) prm;
Window xwin = EwinGetClientXwin(ewin);
if (!_EwinEventEwinCheck("cont", ev, ewin))
return;
switch (ev->type)
{
case ButtonPress:
@ -2407,6 +2442,9 @@ EwinHandleEventsClient(Win win __UNUSED__, XEvent * ev, void *prm)
{
EWin *ewin = (EWin *) prm;
if (!_EwinEventEwinCheck("cli", ev, ewin))
return;
switch (ev->type)
{
case FocusIn:
@ -2482,7 +2520,7 @@ EwinHandleEventsRoot(Win win __UNUSED__, XEvent * ev, void *prm __UNUSED__)
case UnmapNotify:
case EX_EVENT_UNMAP_GONE:
/* Catch clients unmapped after MapRequest but before being reparented */
ewin = EwinFindByClient(ev->xunmap.window);
ewin = _EwinEventEwinFind(ev, ev->xunmap.window);
if (!ewin)
break;
if (ev->type == EX_EVENT_UNMAP_GONE)
@ -2492,7 +2530,7 @@ EwinHandleEventsRoot(Win win __UNUSED__, XEvent * ev, void *prm __UNUSED__)
case DestroyNotify:
/* Catch clients destroyed after MapRequest but before being reparented */
ewin = EwinFindByClient(ev->xdestroywindow.window);
ewin = _EwinEventEwinFind(ev, ev->xdestroywindow.window);
if (!ewin)
break;
EwinEventDestroy(ewin);
@ -2500,7 +2538,7 @@ EwinHandleEventsRoot(Win win __UNUSED__, XEvent * ev, void *prm __UNUSED__)
case ReparentNotify:
case EX_EVENT_REPARENT_GONE:
ewin = EwinFindByClient(ev->xreparent.window);
ewin = _EwinEventEwinFind(ev, ev->xreparent.window);
if (!ewin)
break;
if (ev->type == EX_EVENT_REPARENT_GONE)

View File

@ -66,6 +66,7 @@ struct _ewin {
EObj o;
char type;
Win win_container;
unsigned int serial;
const Border *border;
const Border *normal_border;