Attempt to make client handling more solid.

SVN revision: 14981
This commit is contained in:
Kim Woelders 2005-05-28 11:43:57 +00:00
parent d41aa06aba
commit 661d69880a
5 changed files with 113 additions and 61 deletions

View File

@ -2236,6 +2236,8 @@ Window ECreateEventWindow(Window parent, int x, int y, int w,
Window ECreateFocusWindow(Window parent, int x, int y, int w,
int h);
void EWindowSync(Window win);
void EWindowSetMapped(Window win, int mapped);
Window EWindowGetParent(Window win);
void ESelectInputAdd(Window win, long mask);
void EMoveWindow(Window win, int x, int y);
@ -2288,8 +2290,6 @@ void ESetColor(XColor * pxc, int r, int g, int b);
void EGetColor(const XColor * pxc, int *pr, int *pg, int *pb);
int GetWinDepth(Window win);
Window GetWinParent(Window win);
Window WinGetParent(Window win);
Window WindowAtXY_0(Window base, int bx, int by, int x, int y);
Window WindowAtXY(int x, int y);
Bool PointerAt(int *x, int *y);

View File

@ -1290,7 +1290,8 @@ StackDesktop(int desk)
{
Eprintf("StackDesktop %d:\n", desk);
for (i = 0; i < tot; i++)
Eprintf(" win=%#10lx parent=%#10lx\n", wl[i], GetWinParent(wl[i]));
Eprintf(" win=%#10lx parent=%#10lx\n", wl[i],
EWindowGetParent(wl[i]));
}
XRestackWindows(disp, wl, tot);

View File

@ -432,6 +432,27 @@ EventsCompress(XEvent * evq, int count)
#endif
break;
#if 1 /* FIXME - Do this? */
case ReparentNotify:
n = 0;
for (j = i - 1; j >= 0; j--)
{
ev2 = evq + j;
if (ev2->type == ev->type &&
ev2->xreparent.window == ev->xreparent.window)
{
n++;
ev2->type = 0;
}
}
#if ENABLE_DEBUG_EVENTS
if (n && EventDebug(EDBUG_TYPE_COMPRESSION))
Eprintf("EventsCompress n=%4d %s %#lx\n",
n, EventName(ev->type), ev->xreparent.window);
#endif
break;
#endif
case EX_EVENT_SHAPE_NOTIFY:
n = 0;
for (j = i - 1; j >= 0; j--)

View File

@ -151,8 +151,8 @@ EwinCreate(Window win, int type)
AddItem(ewin, "EWIN", win, LIST_TYPE_EWIN);
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinCreate %#lx frame=%#lx state=%d\n", ewin->client.win,
EoGetWin(ewin), ewin->state);
Eprintf("EwinCreate %#lx frame=%#lx cont=%#lx st=%d\n", ewin->client.win,
EoGetWin(ewin), ewin->win_container, ewin->state);
EventCallbackRegister(EoGetWin(ewin), 0, EwinHandleEventsToplevel, ewin);
EventCallbackRegister(ewin->win_container, 0, EwinHandleEventsContainer,
@ -192,8 +192,8 @@ EwinDestroy(EWin * ewin)
return;
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinDestroy %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("EwinDestroy %#lx st=%d: %s\n", ewin->client.win, ewin->state,
EwinGetName(ewin));
RemoveItem(NULL, ewin->client.win, LIST_FINDBY_ID, LIST_TYPE_EWIN);
EventCallbackUnregister(EoGetWin(ewin), 0, EwinHandleEventsToplevel, ewin);
@ -558,8 +558,8 @@ Adopt(EWin * ewin)
HintsSetClientList();
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("Adopt %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("Adopt %#lx st=%d: %s\n", ewin->client.win, ewin->state,
EwinGetName(ewin));
}
void
@ -907,8 +907,8 @@ EwinWithdraw(EWin * ewin)
/* Only external clients should go here */
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinWithdraw %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("EwinWithdraw %#lx st=%d: %s\n", ewin->client.win, ewin->state,
EwinGetName(ewin));
EGrabServer();
@ -936,8 +936,11 @@ EwinEventMapRequest(EWin * ewin, Window win)
if (ewin->state == EWIN_STATE_WITHDRAWN)
AddToFamily(ewin, win);
else
Eprintf("AddToFamily: Already managing %s %#lx\n", "A",
ewin->client.win);
{
Eprintf("AddToFamily: Already managing %s %#lx\n", "A",
ewin->client.win);
EReparentWindow(ewin->client.win, ewin->win_container, 0, 0);
}
}
else
{
@ -949,6 +952,7 @@ EwinEventMapRequest(EWin * ewin, Window win)
{
Eprintf("AddToFamily: Already managing %s %#lx\n", "B",
ewin->client.win);
EReparentWindow(ewin->client.win, ewin->win_container, 0, 0);
ShowEwin(ewin);
}
else
@ -960,12 +964,30 @@ static void
EwinEventDestroy(EWin * ewin)
{
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinEventDestroy %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("EwinEventDestroy %#lx st=%d: %s\n", ewin->client.win,
ewin->state, EwinGetName(ewin));
EwinDestroy(ewin);
}
static void
EwinEventReparent(EWin * ewin)
{
Window parent;
EGrabServer();
/* Refetch parent window. We cannot rely on the one in the event. */
parent = EWindowGetParent(ewin->client.win);
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinEventReparent %#lx st=%d parent=%#lx: %s\n",
ewin->client.win, ewin->state, parent, EwinGetName(ewin));
if (parent != ewin->win_container)
EwinDestroy(ewin);
EUngrabServer();
}
static void
EwinEventMap(EWin * ewin)
{
@ -974,8 +996,8 @@ EwinEventMap(EWin * ewin)
ewin->state = EWIN_STATE_MAPPED;
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinEventMap %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("EwinEventMap %#lx st=%d: %s\n", ewin->client.win, ewin->state,
EwinGetName(ewin));
/* If first time we may want to focus it (unless during startup) */
if (old_state == EWIN_STATE_NEW)
@ -990,25 +1012,23 @@ static void
EwinEventUnmap(EWin * ewin)
{
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinEventUnmap %#lx %s state=%d\n", ewin->client.win,
EwinGetName(ewin), ewin->state);
Eprintf("EwinEventUnmap %#lx st=%d: %s\n", ewin->client.win, ewin->state,
EwinGetName(ewin));
if (ewin->state == EWIN_STATE_WITHDRAWN)
return;
if (ewin->iconified)
ewin->state = EWIN_STATE_ICONIC;
else
if (ewin->state == EWIN_STATE_ICONIC || !ewin->iconified)
ewin->state = EWIN_STATE_WITHDRAWN;
else
ewin->state = EWIN_STATE_ICONIC;
EwinUnmap1(ewin);
EUnmapWindow(ewin->client.win);
EWindowSetMapped(ewin->client.win, 0);
EoUnmap(ewin);
EwinUnmap2(ewin);
if (ewin->iconified)
if (ewin->state == EWIN_STATE_ICONIC)
return;
if (EwinIsInternal(ewin))
@ -1020,7 +1040,7 @@ EwinEventUnmap(EWin * ewin)
return;
}
if (WinGetParent(ewin->client.win) == ewin->win_container)
if (EWindowGetParent(ewin->client.win) == ewin->win_container)
EwinWithdraw(ewin);
}
@ -1612,7 +1632,7 @@ EwinsSetFree(void)
/* This makes E determine the client window stacking at exit */
EwinInstantUnShade(ewin);
EReparentWindow(ewin->client.win, VRoot.win,
EReparentWindow(ewin->client.win, RRoot.win,
ewin->client.x, ewin->client.y);
}
}
@ -1717,11 +1737,7 @@ EwinHandleEventsContainer(XEvent * ev, void *prm)
EwinEventMap(ewin);
break;
case ReparentNotify:
/* Check if window parent hasn't changed already (compress?) */
if (WinGetParent(ev->xreparent.window) != ev->xreparent.parent)
break;
if (ev->xreparent.parent != ewin->win_container)
EwinEventDestroy(ewin);
EwinEventReparent(ewin);
break;
case GravityNotify:
@ -1818,12 +1834,21 @@ EwinHandleEventsRoot(XEvent * ev, void *prm __UNUSED__)
/* Catch clients destroyed after MapRequest but before being reparented */
ewin = FindItem(NULL, ev->xdestroywindow.window, LIST_FINDBY_ID,
LIST_TYPE_EWIN);
#if 0 /* FIXME - Should not be here - Remove? */
if (!ewin)
ewin = FindEwinByBase(ev->xdestroywindow.window);
#endif
if (ewin)
EwinEventDestroy(ewin);
break;
case ReparentNotify:
ewin = FindItem(NULL, ev->xreparent.window, LIST_FINDBY_ID,
LIST_TYPE_EWIN);
if (ewin)
EwinEventReparent(ewin);
break;
default:
#if 0
Eprintf("EwinHandleEventsRoot: type=%2d win=%#lx\n",

61
src/x.c
View File

@ -474,6 +474,39 @@ EWindowSync(Window win)
xid->depth = depth;
}
void
EWindowSetMapped(Window win, int mapped)
{
EXID *xid;
xid = EXidFind(win);
if (!xid)
return;
xid->mapped = mapped;
}
Window
EWindowGetParent(Window win)
{
EXID *xid;
Window parent, rt;
Window *pch = NULL;
unsigned int nch = 0;
parent = None;
if (!XQueryTree(disp, win, &rt, &parent, &pch, &nch))
parent = None;
else if (pch)
XFree(pch);
xid = EXidFind(win);
if (xid)
xid->parent = parent;
return parent;
}
void
ERegisterWindow(Window win)
{
@ -1208,18 +1241,6 @@ ESync(void)
XSync(disp, False);
}
Window
GetWinParent(Window win)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
return xid->parent;
return 0;
}
int
GetWinDepth(Window win)
{
@ -1230,22 +1251,6 @@ GetWinDepth(Window win)
return d;
}
Window
WinGetParent(Window win)
{
Window parent, rt;
Window *pch = NULL;
unsigned int nch = 0;
if (!XQueryTree(disp, win, &rt, &parent, &pch, &nch))
return None;
if (pch)
XFree(pch);
return parent;
}
Window
WindowAtXY_0(Window base, int bx, int by, int x, int y)
{