Maintain a global window stacking order (not entirely finished).

SVN revision: 9375
This commit is contained in:
Kim Woelders 2004-03-16 22:10:07 +00:00
parent 8a96cf4e25
commit 72a367a6af
10 changed files with 387 additions and 232 deletions

20
src/E.h
View File

@ -1062,8 +1062,6 @@ typedef struct _desk
Window win;
int x, y;
Background *bg;
int num;
EWin **list;
Button *tag;
int current_area_x;
int current_area_y;
@ -1743,8 +1741,6 @@ int ButtonsEventMouseIn(XEvent * ev);
int ButtonsEventMouseOut(XEvent * ev);
/* clone.c */
Clone *CloneEwin(EWin * ewin);
void FreeClone(Clone * c);
void RemoveClones(void);
void CloneDesktop(int d);
@ -1818,7 +1814,6 @@ void InitDesktopControls(void);
void SetDesktopBg(int desk, Background * bg);
void ConformEwinToDesktop(EWin * ewin);
int DesktopAt(int x, int y);
void MoveStickyWindowsToCurrentDesk(void);
void GotoDesktop(int num);
void MoveDesktop(int num, int x, int y);
void RaiseDesktop(int num);
@ -1831,7 +1826,6 @@ void UncoverDesktop(int num);
void MoveEwinToDesktop(EWin * ewin, int num);
void DesktopAddEwinToBottom(EWin * ewin);
void DesktopAddEwinToTop(EWin * ewin);
void DesktopRemoveEwin(EWin * ewin);
void MoveEwinToDesktopAt(EWin * ewin, int num, int x, int y);
void GotoDesktopByEwin(EWin * ewin);
void FloatEwinAboveDesktops(EWin * ewin);
@ -2511,6 +2505,20 @@ void SoundExit(void);
int SoundPlay(const char *name);
int SoundFree(const char *name);
/* stacking.c */
typedef struct _ewinlist EWinList;
extern EWinList EwinListFocus;
extern EWinList EwinListStack;
void EwinListAdd(EWinList * ewl, EWin * ewin);
void EwinListDelete(EWinList * ewl, EWin * ewin);
int EwinListRaise(EWinList * ewl, EWin * ewin, int mode);
int EwinListLower(EWinList * ewl, EWin * ewin, int mode);
EWin **EwinListGetForDesktop(int desk, int *num);
EWin **EwinListGetStacking(int *num);
int EwinListStackingRaise(EWin * ewin);
int EwinListStackingLower(EWin * ewin);
int EwinListFocusRaise(EWin * ewin);
/* startup.c */
void AddE(void);
void CreateStartupDisplay(char start);

View File

@ -68,6 +68,7 @@ enlightenment_SOURCES = \
slideout.c \
snaps.c \
sound.c \
stacking.c \
startup.c \
sticky.c \
tclass.c \

View File

@ -1162,30 +1162,27 @@ FindEwinInList(EWin * ewin, EWin ** gwins, int num)
static int
DoRaiseLower(EWin * ewin, void *params, int nogroup)
{
EWin **gwins;
int i, num, j, raise = 0;
EWin **gwins, **lst;
int gnum, j, raise = 0;
int i, num;
EDBUG(6, "doRaiseLower");
gwins = ListWinGroupMembersForEwin(ewin, ACTION_RAISE_LOWER, nogroup, &num);
for (j = 0; j < num; j++)
lst = EwinListGetForDesktop(ewin->desktop, &num);
gwins = ListWinGroupMembersForEwin(ewin, ACTION_RAISE_LOWER, nogroup, &gnum);
for (j = 0; j < gnum; j++)
{
ewin = gwins[j];
if (desks.desk[ewin->desktop].list)
for (i = 0; i < num - 1; i++)
{
for (i = 0; i < desks.desk[ewin->desktop].num - 1; i++)
if (lst[i]->layer == ewin->layer &&
(lst[i] == ewin || !FindEwinInList(lst[i], gwins, gnum)))
{
if (desks.desk[ewin->desktop].list[i]->layer == ewin->layer
&& (desks.desk[ewin->desktop].list[i] == ewin
|| !FindEwinInList(desks.desk[ewin->desktop].list[i],
gwins, num)))
{
if (desks.desk[ewin->desktop].list[i] != ewin)
raise = 1;
if (lst[i] != ewin)
raise = 1;
j = num;
break;
}
j = gnum;
break;
}
}
}

View File

@ -149,27 +149,32 @@ EWin *
GetEwinPointerInClient(void)
{
Window rt, ch;
int dum, px, py, d, i;
int dum, px, py, d;
EWin **lst;
int i, num;
EDBUG(5, "GetEwinPointerInClient");
d = DESKTOPS_WRAP_NUM(DesktopAt(mode.x, mode.y));
d = DesktopAt(mode.x, mode.y);
XQueryPointer(disp, desks.desk[d].win, &rt, &ch, &(mode.x), &(mode.y), &dum,
&dum, (unsigned int *)&dum);
px = mode.x - desks.desk[d].x;
py = mode.y - desks.desk[d].y;
for (i = 0; i < desks.desk[d].num; i++)
lst = EwinListGetForDesktop(d, &num);
for (i = 0; i < num; i++)
{
int x, y, w, h;
x = desks.desk[d].list[i]->x;
y = desks.desk[d].list[i]->y;
w = desks.desk[d].list[i]->w;
h = desks.desk[d].list[i]->h;
x = lst[i]->x;
y = lst[i]->y;
w = lst[i]->w;
h = lst[i]->h;
if ((px >= x) && (py >= y) && (px < (x + w)) && (py < (y + h))
&& (desks.desk[d].list[i]->visible))
EDBUG_RETURN(desks.desk[d].list[i]);
&& (lst[i]->visible))
EDBUG_RETURN(lst[i]);
}
EDBUG_RETURN(NULL);
}
@ -1319,6 +1324,9 @@ CreateEwin()
&att);
FocusEwinSetGrabs(ewin);
GrabButtonGrabs(ewin);
EwinListAdd(&EwinListStack, ewin);
EwinListAdd(&EwinListFocus, ewin);
EDBUG_RETURN(ewin);
}
@ -1332,6 +1340,9 @@ FreeEwin(EWin * ewin)
if (!ewin)
EDBUG_RETURN_;
EwinListDelete(&EwinListStack, ewin);
EwinListDelete(&EwinListFocus, ewin);
HintsSetClientList();
if (GetZoomEWin() == ewin)
@ -1339,8 +1350,6 @@ FreeEwin(EWin * ewin)
UnmatchEwinToSnapInfo(ewin);
DesktopRemoveEwin(ewin);
PagerEwinOutsideAreaUpdate(ewin);
PagerHideAllHi();
@ -1811,7 +1820,6 @@ FloatEwin(EWin * ewin)
if (call_depth > 256)
EDBUG_RETURN_;
ewin->floating = 1;
DesktopRemoveEwin(ewin);
ewin->desktop = 0;
ConformEwinToDesktop(ewin);
RaiseEwin(ewin);
@ -1898,14 +1906,19 @@ RaiseEwin(EWin * ewin)
static int call_depth = 0;
EDBUG(3, "RaiseEwin");
call_depth++;
if (call_depth > 256)
EDBUG_RETURN_;
call_depth++;
#if 0
printf("RaiseEwin %#lx %s\n", ewin->client.win, EwinGetTitle(ewin));
#endif
if (ewin->win)
{
if (ewin->floating)
XRaiseWindow(disp, ewin->win);
{
XRaiseWindow(disp, ewin->win);
}
else
{
DesktopAddEwinToTop(ewin);
@ -1925,6 +1938,7 @@ RaiseEwin(EWin * ewin)
RestackEwin(ewin);
}
}
call_depth--;
EDBUG_RETURN_;
}
@ -1935,9 +1949,13 @@ LowerEwin(EWin * ewin)
static int call_depth = 0;
EDBUG(3, "LowerEwin");
call_depth++;
if (call_depth > 256)
EDBUG_RETURN_;
call_depth++;
#if 0
printf("LowerEwin %#lx %s\n", ewin->client.win, EwinGetTitle(ewin));
#endif
if ((ewin->win) && (!ewin->floating))
{
if (ewin->has_transients)
@ -1956,6 +1974,7 @@ LowerEwin(EWin * ewin)
DesktopAddEwinToBottom(ewin);
RestackEwin(ewin);
}
call_depth--;
EDBUG_RETURN_;
}

View File

@ -22,9 +22,13 @@
*/
#include "E.h"
#define ENABLE_CLONING 0
#if ENABLE_CLONING
static int calls = 0;
Clone *
static Clone *
CloneEwin(EWin * ewin)
{
Clone *c;
@ -63,16 +67,19 @@ CloneEwin(EWin * ewin)
return c;
}
void
static void
FreeClone(Clone * c)
{
XDestroyWindow(disp, c->win);
Efree(c);
}
#endif /* ENABLE_CLONING */
void
RemoveClones(void)
{
#if ENABLE_CLONING /* FIXME What is this? */
Clone *c;
calls--;
@ -82,11 +89,13 @@ RemoveClones(void)
FreeClone(c);
calls = 0;
}
#endif
}
void
CloneDesktop(int d)
{
#if ENABLE_CLONING /* FIXME What is this? */
int i, num;
Clone **clist = NULL;
@ -136,4 +145,5 @@ CloneDesktop(int d)
}
Efree(clist);
}
#endif
}

View File

@ -759,8 +759,6 @@ InitDesktopBgs()
d = &desks.desk[i];
d->bg = NULL;
desks.order[i] = i;
d->num = 0;
d->list = NULL;
d->tag = NULL;
d->x = 0;
d->y = 0;
@ -1122,7 +1120,6 @@ ConformEwinToDesktop(EWin * ewin)
}
else if (ewin->floating)
{
DesktopRemoveEwin(ewin);
xo = desks.desk[ewin->desktop].x;
yo = desks.desk[ewin->desktop].y;
if ((ewin->parent != root.win) && (ewin->floating == 2))
@ -1171,39 +1168,31 @@ DesktopAt(int x, int y)
EDBUG_RETURN(0);
}
void
static void
MoveStickyWindowsToCurrentDesk(void)
{
EWin **lst, *ewin, *last_ewin;
int i, num;
lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN);
if ((lst) && (num > 0))
lst = EwinListGetStacking(&num);
last_ewin = NULL;
for (i = 0; i < num; i++)
{
last_ewin = NULL;
for (i = 0; i < num; i++)
{
ewin = (EWin *) lst[i];
if (ewin->sticky)
{
DesktopRemoveEwin(ewin);
ewin->desktop = DESKTOPS_WRAP_NUM(desks.current);
ewin->parent = desks.desk[ewin->desktop].win;
EReparentWindow(disp, ewin->win,
desks.desk[ewin->desktop].win, root.w,
root.h);
XLowerWindow(disp, ewin->win);
EMoveWindow(disp, ewin->win, ewin->x, ewin->y);
DesktopAddEwinToTop(ewin);
HintsSetWindowArea(ewin);
HintsSetWindowDesktop(ewin);
last_ewin = ewin;
}
}
if (last_ewin)
RestackEwin(last_ewin);
Efree(lst);
ewin = lst[i];
if (!ewin->sticky)
continue;
ewin->desktop = desks.current;
ewin->parent = desks.desk[ewin->desktop].win;
EReparentWindow(disp, ewin->win,
desks.desk[ewin->desktop].win, root.w, root.h);
EMoveWindow(disp, ewin->win, ewin->x, ewin->y);
HintsSetWindowArea(ewin);
HintsSetWindowDesktop(ewin);
last_ewin = ewin;
}
if (last_ewin)
RestackEwin(last_ewin);
}
void
@ -1289,7 +1278,8 @@ GotoDesktop(int desk)
{
GetWinXY(desks.desk[desk].win, &x, &y);
SlideWindowTo(desks.desk[desk].win, desks.desk[desk].x,
desks.desk[desk].y, 0, 0, conf.desks.slidespeed);
desks.desk[desk].y, 0, 0,
conf.desks.slidespeed);
RaiseDesktop(desk);
}
StackDesktops();
@ -1596,7 +1586,7 @@ StackDesktop(int desk)
_APPEND_TO_WIN_LIST(init_win2);
}
lst = (EWin **) ListItemType(&wnum, LIST_TYPE_EWIN);
lst = EwinListGetStacking(&wnum);
blst = (Button **) ListItemType(&bnum, LIST_TYPE_BUTTON);
/* Sticky buttons */
@ -1646,9 +1636,11 @@ StackDesktop(int desk)
}
/* Normal EWins on this desk */
for (i = 0; i < desks.desk[desk].num; i++)
for (i = 0; i < wnum; i++)
{
ewin = desks.desk[desk].list[i];
ewin = lst[i];
if (EwinGetDesk(ewin) != desk || ewin->floating)
continue;
_APPEND_TO_WIN_LIST(ewin->win);
if (ewin->win == mode.menu_win_covered)
@ -1678,8 +1670,6 @@ StackDesktop(int desk)
if (wl)
Efree(wl);
if (lst)
Efree(lst);
if (blst)
Efree(blst);
@ -1709,7 +1699,6 @@ MoveEwinToDesktop(EWin * ewin, int desk)
EDBUG(3, "MoveEwinToDesktop");
/* ewin->sticky = 0; */
ewin->floating = 0;
DesktopRemoveEwin(ewin);
pdesk = ewin->desktop;
ewin->desktop = DESKTOPS_WRAP_NUM(desk);
DesktopAddEwinToTop(ewin);
@ -1734,122 +1723,33 @@ MoveEwinToDesktop(EWin * ewin, int desk)
EDBUG_RETURN_;
}
void
DesktopRemoveEwin(EWin * ewin)
{
int i, j;
EDBUG(5, "DesktopRemoveEwin");
if ((ewin->desktop < 0)
|| (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1))
EDBUG_RETURN_;
for (i = 0; i < desks.desk[ewin->desktop].num; i++)
{
if (desks.desk[ewin->desktop].list[i] == ewin)
{
for (j = i; j < desks.desk[ewin->desktop].num - 1; j++)
desks.desk[ewin->desktop].list[j] =
desks.desk[ewin->desktop].list[j + 1];
desks.desk[ewin->desktop].num--;
if (desks.desk[ewin->desktop].num <= 0)
{
desks.desk[ewin->desktop].num = 0;
if (desks.desk[ewin->desktop].list)
Efree(desks.desk[ewin->desktop].list);
desks.desk[ewin->desktop].list = NULL;
}
else
{
desks.desk[ewin->desktop].list =
Erealloc(desks.desk[ewin->desktop].list,
desks.desk[ewin->desktop].num * sizeof(EWin *));
}
EDBUG_RETURN_;
}
}
EDBUG_RETURN_;
}
void
DesktopAddEwinToTop(EWin * ewin)
{
int i, j;
EDBUG(5, "DesktopAddEwinToTop");
if ((ewin->desktop < 0)
|| (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1))
EDBUG_RETURN_;
DesktopRemoveEwin(ewin);
desks.desk[ewin->desktop].num++;
if (desks.desk[ewin->desktop].list)
desks.desk[ewin->desktop].list =
Erealloc(desks.desk[ewin->desktop].list,
desks.desk[ewin->desktop].num * sizeof(EWin *));
else
desks.desk[ewin->desktop].list = Emalloc(sizeof(EWin *));
if (desks.desk[ewin->desktop].num == 1)
{
desks.desk[ewin->desktop].list[0] = ewin;
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
for (i = 0; i < desks.desk[ewin->desktop].num - 1; i++)
{
if (desks.desk[ewin->desktop].list[i]->layer <= ewin->layer)
{
for (j = desks.desk[ewin->desktop].num - 1; j > i; j--)
desks.desk[ewin->desktop].list[j] =
desks.desk[ewin->desktop].list[j - 1];
desks.desk[ewin->desktop].list[i] = ewin;
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
}
desks.desk[ewin->desktop].list[desks.desk[ewin->desktop].num - 1] = ewin;
EwinListStackingRaise(ewin);
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
void
DesktopAddEwinToBottom(EWin * ewin)
{
int i, j;
EDBUG(5, "DesktopAddEwinToBottom");
if ((ewin->desktop < 0)
|| (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1))
EDBUG_RETURN_;
DesktopRemoveEwin(ewin);
desks.desk[ewin->desktop].num++;
if (desks.desk[ewin->desktop].list)
desks.desk[ewin->desktop].list =
Erealloc(desks.desk[ewin->desktop].list,
desks.desk[ewin->desktop].num * sizeof(EWin *));
else
desks.desk[ewin->desktop].list = Emalloc(sizeof(EWin *));
if (desks.desk[ewin->desktop].num == 1)
{
desks.desk[ewin->desktop].list[0] = ewin;
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
for (i = 0; i < desks.desk[ewin->desktop].num - 1; i++)
{
if (desks.desk[ewin->desktop].list[i]->layer < ewin->layer)
{
for (j = desks.desk[ewin->desktop].num - 1; j > i; j--)
desks.desk[ewin->desktop].list[j] =
desks.desk[ewin->desktop].list[j - 1];
desks.desk[ewin->desktop].list[i] = ewin;
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
}
desks.desk[ewin->desktop].list[desks.desk[ewin->desktop].num - 1] = ewin;
EwinListStackingLower(ewin);
ForceUpdatePagersForDesktop(ewin->desktop);
EDBUG_RETURN_;
}
@ -1863,7 +1763,6 @@ MoveEwinToDesktopAt(EWin * ewin, int desk, int x, int y)
ewin->floating = 0;
if (desk != ewin->desktop && !ewin->sticky)
{
DesktopRemoveEwin(ewin);
ForceUpdatePagersForDesktop(ewin->desktop);
ewin->desktop = DESKTOPS_WRAP_NUM(desk);
DesktopAddEwinToTop(ewin);

View File

@ -166,21 +166,6 @@ atom_list_set(Atom * atoms, int size, int *count, Atom atom, int set)
}
}
/*
* Return index of window in list, -1 if not found.
* Search starts at end (utility to help finding the stacking order).
*/
static int
winlist_rindex(Window * wl, int len, Window win)
{
int i;
for (i = len - 1; i >= 0; i--)
if (win == wl[i])
break;
return i;
}
/*
* Initialize EWMH stuff
*/
@ -382,10 +367,11 @@ void
EWMH_SetClientList(void)
{
Window *wl;
int i, j, k, nwin, num;
int i, nwin, num;
EWin **lst;
EDBUG(6, "EWMH_SetClientList");
/* Mapping order */
lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN);
wl = NULL;
@ -394,39 +380,24 @@ EWMH_SetClientList(void)
{
wl = Emalloc(sizeof(Window) * num);
for (i = 0; i < num; i++)
{
EWin *ewin = lst[i];
if (ewin->iconified == 4)
continue;
wl[nwin++] = ewin->client.win;
}
wl[nwin++] = lst[i]->client.win;
_ATOM_SET_WINDOW(_NET_CLIENT_LIST, root.win, wl, nwin);
Efree(lst);
}
_ATOM_SET_WINDOW(_NET_CLIENT_LIST, root.win, wl, nwin);
if (lst)
Efree(lst);
/*
* Stacking order.
* We will only bother ourselves with the ones on this desktop.
*/
num = desks.desk[desks.current].num;
lst = desks.desk[desks.current].list;
for (i = j = 0; i < num; i++)
{
Window win = lst[i]->client.win;
k = winlist_rindex(wl, nwin - j, win);
if (k < 0)
continue;
/* Swap 'em */
wl[k] = wl[nwin - 1 - j];
wl[nwin - 1 - j] = win;
j++;
}
/* Stacking order */
lst = EwinListGetStacking(&num);
/* FIXME: num must be unchanged here! Check! */
if (num != nwin)
printf("*** ERROR: %s %d\n", __FILE__, __LINE__);
nwin = 0;
for (i = num - 1; i >= 0; i--)
wl[nwin++] = lst[i]->client.win;
_ATOM_SET_WINDOW(_NET_CLIENT_LIST_STACKING, root.win, wl, nwin);
if (wl)
Efree(wl);
EDBUG_RETURN_;
}

View File

@ -311,6 +311,7 @@ FocusToEWin(EWin * ewin, int why)
NULL);
SoundPlay("SOUND_FOCUS_SET");
EwinListFocusRaise(ewin);
exit:
ICCCM_Cmap(ewin);
ICCCM_Focus(ewin);

View File

@ -104,13 +104,14 @@ PagerUpdateTimeout(int val, void *data)
p->update_phase++;
if (p->update_phase >= p->h)
{
int i;
int i, num;
EWin **lst;
for (i = 0; i < desks.desk[p->desktop].num; i++)
PagerEwinUpdateFromPager(p, desks.desk[p->desktop].list[i]);
lst = EwinListGetForDesktop(p->desktop, &num);
for (i = 0; i < num; i++)
PagerEwinUpdateFromPager(p, lst[i]);
p->update_phase = 0;
}
val = 0;
}
Pager *
@ -222,9 +223,11 @@ PagerMoveResize(EWin * ewin, int resize)
{
Pager *p = ewin->pager;
int w, h;
int ax, ay, i, cx, cy;
int ax, ay, cx, cy;
char pq;
ImageClass *ic;
EWin **lst;
int i, num;
if (!conf.pagers.enable || !p)
return;
@ -271,8 +274,9 @@ PagerMoveResize(EWin * ewin, int resize)
}
queue_up = pq;
for (i = 0; i < desks.desk[p->desktop].num; i++)
PagerEwinUpdateMini(p, desks.desk[p->desktop].list[i]);
lst = EwinListGetForDesktop(p->desktop, &num);
for (i = 0; i < num; i++)
PagerEwinUpdateMini(p, lst[i]);
}
static void
@ -581,9 +585,11 @@ PagerEwinUpdateFromPager(Pager * p, EWin * ewin)
void
PagerRedraw(Pager * p, char newbg)
{
int i, x, y, ax, ay, cx, cy;
int x, y, ax, ay, cx, cy;
GC gc;
XGCValues gcv;
EWin **lst;
int i, num;
if (!conf.pagers.enable || mode.mode == MODE_DESKSWITCH)
return;
@ -700,12 +706,13 @@ PagerRedraw(Pager * p, char newbg)
p->h / ay, x * (p->w / ax), y * (p->h / ay));
}
for (i = desks.desk[p->desktop].num - 1; i >= 0; i--)
lst = EwinListGetForDesktop(p->desktop, &num);
for (i = num - 1; i >= 0; i--)
{
EWin *ewin;
int wx, wy, ww, wh;
ewin = desks.desk[p->desktop].list[i];
ewin = lst[i];
if (!ewin->iconified && ewin->visible)
{
wx = ((ewin->x + (cx * root.w)) * (p->w / ax)) / root.w;
@ -749,7 +756,9 @@ PagerRedraw(Pager * p, char newbg)
void
PagerForceUpdate(Pager * p)
{
int ww, hh, xx, yy, ax, ay, cx, cy, i;
int ww, hh, xx, yy, ax, ay, cx, cy;
EWin **lst;
int i, num;
if (!conf.pagers.enable || mode.mode == MODE_DESKSWITCH)
return;
@ -798,8 +807,9 @@ PagerForceUpdate(Pager * p)
ScaleRect(p->pmap, root.win, 0, 0, xx, yy, root.w, root.h, ww, hh);
XClearWindow(disp, p->win);
for (i = 0; i < desks.desk[p->desktop].num; i++)
PagerEwinUpdateFromPager(p, desks.desk[p->desktop].list[i]);
lst = EwinListGetForDesktop(p->desktop, &num);
for (i = 0; i < num; i++)
PagerEwinUpdateFromPager(p, lst[i]);
}
void
@ -869,7 +879,9 @@ PagerEwinOutsideAreaUpdate(EWin * ewin)
static EWin *
EwinInPagerAt(Pager * p, int x, int y)
{
int i, wx, wy, ww, wh, ax, ay, cx, cy;
int wx, wy, ww, wh, ax, ay, cx, cy;
EWin **lst;
int i, num;
if (!conf.pagers.enable)
return NULL;
@ -877,11 +889,12 @@ EwinInPagerAt(Pager * p, int x, int y)
GetAreaSize(&ax, &ay);
cx = desks.desk[p->desktop].current_area_x;
cy = desks.desk[p->desktop].current_area_y;
for (i = 0; i < desks.desk[p->desktop].num; i++)
lst = EwinListGetForDesktop(p->desktop, &num);
for (i = 0; i < num; i++)
{
EWin *ewin;
ewin = desks.desk[p->desktop].list[i];
ewin = lst[i];
if ((ewin->visible) && (!ewin->iconified))
{
wx = ((ewin->x + (cx * root.w)) * (p->w / ax)) / root.w;
@ -892,6 +905,7 @@ EwinInPagerAt(Pager * p, int x, int y)
return ewin;
}
}
return NULL;
}
@ -1972,7 +1986,7 @@ PagersEventMouseIn(XEvent * ev)
p = FindPager(win);
if (p)
{
#if 0
#if 0 /* Nothing done here */
PagerHandleMotion(p, win, ev->xcrossing.x, ev->xcrossing.y,
PAGER_EVENT_MOUSE_IN);
#endif

235
src/stacking.c Normal file
View File

@ -0,0 +1,235 @@
/*
* Copyright (C) 2004 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#define ENABLE_DEBUG_STACKING 1
struct _ewinlist
{
const char *name;
int nalloc;
int nwins;
EWin **list;
};
#if ENABLE_DEBUG_STACKING
void
EwinListShow(const char *txt, EWinList * ewl)
{
int i;
EWin *ewin;
if (!EventDebug(129))
return;
printf("%s-%s:\n", ewl->name, txt);
for (i = 0; i < ewl->nwins; i++)
{
ewin = ewl->list[i];
printf(" %2d: %#lx %d %s\n", i, ewin->client.win, ewin->layer,
EwinGetTitle(ewin));
}
}
#else
#define EwinListShow(txt, ewl)
#endif
int
EwinListGetIndex(EWinList * ewl, EWin * ewin)
{
int i;
for (i = 0; i < ewl->nwins; i++)
if (ewl->list[i] == ewin)
return i;
return -1;
}
void
EwinListAdd(EWinList * ewl, EWin * ewin)
{
int i;
/* Quit if already in list */
i = EwinListGetIndex(ewl, ewin);
if (i >= 0)
return;
if (ewl->nwins >= ewl->nalloc)
{
ewl->nalloc += 16;
ewl->list = (EWin **) Erealloc(ewl->list, ewl->nalloc * sizeof(EWin *));
}
/* Add to end */
ewl->list[ewl->nwins] = ewin;
ewl->nwins++;
EwinListShow("EwinListAdd", ewl);
}
void
EwinListDelete(EWinList * ewl, EWin * ewin)
{
int i, n;
/* Quit if not in list */
i = EwinListGetIndex(ewl, ewin);
if (i < 0)
return;
ewl->nwins--;
n = ewl->nwins - i;
if (n > 0)
{
memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EWin *));
}
else if (ewl->nwins <= 0)
{
/* Enables autocleanup at shutdown, if ever implemented */
Efree(ewl->list);
ewl->list = NULL;
}
EwinListShow("EwinListDelete", ewl);
}
int
EwinListLower(EWinList * ewl, EWin * ewin, int mode)
{
int i, j, n;
/* Quit if not in list */
i = EwinListGetIndex(ewl, ewin);
if (i < 0)
return 0;
j = ewl->nwins - 1;
if (mode)
{
/* Take the layer into account */
for (; j > i; j--)
if (ewin->layer <= ewl->list[j]->layer)
break;
}
n = j - i;
if (n > 0)
{
memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EWin *));
ewl->list[j] = ewin;
}
EwinListShow("EwinListLower", ewl);
return n;
}
int
EwinListRaise(EWinList * ewl, EWin * ewin, int mode)
{
int i, j, n;
/* Quit if not in list */
i = EwinListGetIndex(ewl, ewin);
if (i < 0)
return 0;
j = 0;
if (mode)
{
/* Take the layer into account */
for (; j < i; j++)
if (ewin->layer >= ewl->list[j]->layer)
break;
}
n = i - j;
if (n > 0)
{
memmove(ewl->list + j + 1, ewl->list + j, n * sizeof(EWin *));
ewl->list[j] = ewin;
}
EwinListShow("EwinListRaise", ewl);
return n;
}
/*
* The global stacking and focus lists
*/
EWinList EwinListFocus = { "Focus" };
EWinList EwinListStack = { "Stack" };
EWin **
EwinListGetStacking(int *num)
{
*num = EwinListStack.nwins;
return EwinListStack.list;
}
EWin **
EwinListGetForDesktop(int desk, int *num)
{
static EWin **lst = NULL;
static int nalloc;
int i, n, nwins;
EWin *ewin;
/* TBD: Maintain per desktop lists? Not sure it's worth while */
nwins = EwinListStack.nwins;
if (nalloc < nwins)
{
nalloc = nwins;
lst = Erealloc(lst, nalloc * sizeof(EWin *));
}
n = 0;
for (i = 0; i < nwins; i++)
{
ewin = EwinListStack.list[i];
if (EwinGetDesk(ewin) == desk)
lst[n++] = ewin;
}
*num = n;
return lst;
}
int
EwinListStackingRaise(EWin * ewin)
{
return EwinListRaise(&EwinListStack, ewin, 1);
}
int
EwinListStackingLower(EWin * ewin)
{
return EwinListLower(&EwinListStack, ewin, 1);
}
int
EwinListFocusRaise(EWin * ewin)
{
return EwinListRaise(&EwinListFocus, ewin, 0);
}