forked from e16/e16
1
0
Fork 0

Another attempt to get shape right.

SVN revision: 14886
This commit is contained in:
Kim Woelders 2005-05-21 20:58:18 +00:00
parent 68bcc0dd12
commit ad3b5c7d2e
11 changed files with 452 additions and 420 deletions

43
src/E.h
View File

@ -1244,7 +1244,7 @@ void EwinBorderSelect(EWin * ewin);
void EwinBorderDetach(EWin * ewin);
void EwinBorderSetTo(EWin * ewin, const Border * b);
void EwinBorderDraw(EWin * ewin, int do_shape, int do_paint);
void EwinBorderCalcSizes(EWin * ewin);
void EwinBorderCalcSizes(EWin * ewin, int propagate);
void EwinBorderMinShadeSize(EWin * ewin, int *mw, int *mh);
void EwinBorderUpdateInfo(EWin * ewin);
void EwinBorderUpdateState(EWin * ewin);
@ -1478,7 +1478,6 @@ void DockDestroy(EWin * ewin);
Imlib_Image *ELoadImage(const char *file);
void DrawEwinShape(EWin * ewin, int md, int x, int y, int w,
int h, char firstlast);
void PropagateShapes(Window win);
/* econfig.c */
void ConfigurationLoad(void);
@ -1594,7 +1593,6 @@ EWin *AddInternalToFamily(Window win, const char *bname, int type,
void *ptr,
void (*init) (EWin * ewin, void *ptr));
void EwinReparent(EWin * ewin, Window parent);
void SyncBorderToEwin(EWin * ewin);
Window EwinGetClientWin(const EWin * ewin);
const char *EwinGetName(const EWin * ewin);
const char *EwinGetIconName(const EWin * ewin);
@ -2251,6 +2249,25 @@ void EDestroyWindow(Window win);
void EMapWindow(Window win);
void EMapRaised(Window win);
void EUnmapWindow(Window win);
void EReparentWindow(Window win, Window parent, int x, int y);
int EGetGeometry(Window win, Window * root_return,
int *x, int *y, int *w, int *h, int *bw,
int *depth);
void EConfigureWindow(Window win, unsigned int mask,
XWindowChanges * wc);
void ESetWindowBackgroundPixmap(Window win, Pixmap pmap);
void ESetWindowBackground(Window win, int col);
#define ESelectInput(win, mask) XSelectInput(disp, win, mask)
#define EGetWindowAttributes(win, attr) XGetWindowAttributes(disp, win, attr)
#define EChangeWindowAttributes(win, mask, attr) XChangeWindowAttributes(disp, win, mask, attr)
#define ERaiseWindow(win) XRaiseWindow(disp, win)
#define ELowerWindow(win) XLowerWindow(disp, win)
#define EClearWindow(win) XClearWindow(disp, win)
#define EClearArea(win, x, y, w, h, exp) XClearArea(disp, win, x, y, w, h, exp)
#define ECreatePixmap(draw, w, h, dep) XCreatePixmap(disp, draw, w, h, dep)
#define EFreePixmap(pmap) XFreePixmap(disp, pmap)
void EShapeCombineMask(Window win, int dest, int x, int y,
Pixmap pmap, int op);
void EShapeCombineMaskTiled(Window win, int dest, int x, int y,
@ -2262,26 +2279,10 @@ void EShapeCombineShape(Window win, int dest, int x, int y,
Window src_win, int src_kind, int op);
XRectangle *EShapeGetRectangles(Window win, int dest, int *rn,
int *ord);
void EReparentWindow(Window win, Window parent, int x, int y);
int EGetGeometry(Window win, Window * root_return,
int *x, int *y, int *w, int *h, int *bw,
int *depth);
void EConfigureWindow(Window win, unsigned int mask,
XWindowChanges * wc);
void ESetWindowBackgroundPixmap(Window win, Pixmap pmap);
void ESetWindowBackground(Window win, int col);
int EShapeCopy(Window dst, Window src);
void EShapePropagate(Window win);
Pixmap EWindowGetShapePixmap(Window win);
#define ESelectInput(win, mask) XSelectInput(disp, win, mask)
#define EGetWindowAttributes(win, attr) XGetWindowAttributes(disp, win, attr)
#define EChangeWindowAttributes(win, mask, attr) XChangeWindowAttributes(disp, win, mask, attr)
#define ERaiseWindow(win) XRaiseWindow(disp, win)
#define ELowerWindow(win) XLowerWindow(disp, win)
#define EClearWindow(win) XClearWindow(disp, win)
#define EClearArea(win, x, y, w, h, exp) XClearArea(disp, win, x, y, w, h, exp)
#define ECreatePixmap(draw, w, h, dep) XCreatePixmap(disp, draw, w, h, dep)
#define EFreePixmap(pmap) XFreePixmap(disp, pmap)
GC ECreateGC(Drawable d, unsigned long mask, XGCValues * val);
int EFreeGC(GC gc);

View File

@ -34,16 +34,6 @@
static void BorderWinpartHandleEvents(XEvent * ev, void *prm);
static void BorderFrameHandleEvents(XEvent * ev, void *prm);
void
SyncBorderToEwin(EWin * ewin)
{
const Border *b;
b = ewin->border;
ICCCM_GetShapeInfo(ewin);
EwinSetBorder(ewin, b, 1);
}
void
EwinBorderUpdateState(EWin * ewin)
{
@ -366,7 +356,7 @@ BorderWinpartCalc(EWin * ewin, int i, int ww, int hh)
}
void
EwinBorderCalcSizes(EWin * ewin)
EwinBorderCalcSizes(EWin * ewin, int propagate)
{
int i, ww, hh;
char reshape;
@ -394,10 +384,14 @@ EwinBorderCalcSizes(EWin * ewin)
ewin->bits[i].no_expose = 1;
}
#if 0 /* Debug */
Eprintf("EwinBorderCalcSizes prop=%d reshape=%d\n", propagate, reshape);
#endif
if (reshape)
{
ewin->shapedone = 0;
EwinPropagateShapes(ewin);
if (propagate)
EwinPropagateShapes(ewin);
}
}
@ -429,9 +423,6 @@ EwinBorderSelect(EWin * ewin)
if (b && strncmp(b->name, "__", 2))
goto done;
ICCCM_GetShapeInfo(ewin);
ewin->shapedone = 0;
if ((!ewin->client.mwm_decor_title && !ewin->client.mwm_decor_border) ||
(Conf.dock.enable && ewin->docked))
b = FindItem("BORDERLESS", 0, LIST_FINDBY_NAME, LIST_TYPE_BORDER);
@ -567,7 +558,8 @@ EwinBorderSetTo(EWin * ewin, const Border * b)
if (!ewin->shaded)
EMoveWindow(ewin->win_container, b->border.left, b->border.top);
EwinBorderCalcSizes(ewin);
ewin->shapedone = 0;
EwinBorderCalcSizes(ewin, 0);
SnapshotEwinUpdate(ewin, SNAP_USE_BORDER);
}
@ -581,7 +573,6 @@ EwinSetBorder(EWin * ewin, const Border * b, int apply)
if (apply)
{
EwinBorderSetTo(ewin, b);
ICCCM_MatchSize(ewin);
MoveResizeEwin(ewin, EoGetX(ewin), EoGetY(ewin),
ewin->client.w, ewin->client.h);
}

View File

@ -1116,112 +1116,3 @@ ELoadImage(const char *file)
return NULL;
}
void
PropagateShapes(Window win)
{
Window rt, par, *list = NULL;
unsigned int i, num, num_rects;
int k, rn, ord;
int x, y, xx, yy, ww, hh, d;
XRectangle *rects, *rl;
XWindowAttributes att;
if (!EGetGeometry(win, &rt, &xx, &yy, &ww, &hh, &d, &d))
return;
if ((ww <= 0) || (hh <= 0))
return;
#if 0
Eprintf("PropagateShapes %#lx %d,%d %dx%d\n", win, xx, yy, ww, hh);
#endif
XQueryTree(disp, win, &rt, &par, &list, &num);
if (!list)
return;
num_rects = 0;
rects = NULL;
/* go through all child windows and create/inset spans */
for (i = 0; i < num; i++)
{
XGetWindowAttributes(disp, list[i], &att);
x = att.x;
y = att.y;
if ((att.class == InputOutput) && (att.map_state != IsUnmapped))
{
rl = EShapeGetRectangles(list[i], ShapeBounding, &rn, &ord);
if (rl)
{
if (rn > 0)
{
rects = Erealloc(rects,
(num_rects + rn) * sizeof(XRectangle));
/* go through all clip rects in thsi window's shape */
for (k = 0; k < rn; k++)
{
/* for each clip rect, add it to the rect list */
rects[num_rects + k].x = x + rl[k].x;
rects[num_rects + k].y = y + rl[k].y;
rects[num_rects + k].width = rl[k].width;
rects[num_rects + k].height = rl[k].height;
}
num_rects += rn;
}
Efree(rl);
}
else
{
rects = Erealloc(rects, (num_rects + 1) * sizeof(XRectangle));
rects[num_rects].x = x;
rects[num_rects].y = y;
rects[num_rects].width = att.width;
rects[num_rects].height = att.height;
num_rects++;
}
}
}
#if 0
for (i = 0; i < num_rects; i++)
Eprintf("%3d %4d,%4d %4dx%4d\n", i, rects[i].x, rects[i].y,
rects[i].width, rects[i].height);
#endif
/* set the rects as the shape mask */
if (rects)
{
EShapeCombineRectangles(win, ShapeBounding, 0, 0, rects,
num_rects, ShapeSet, Unsorted);
/* Limit shape to window extents */
rects[0].x = 0;
rects[0].y = 0;
rects[0].width = ww;
rects[0].height = hh;
EShapeCombineRectangles(win, ShapeBounding, 0, 0, rects,
1, ShapeIntersect, Unsorted);
Efree(rects);
rl = NULL;
rl = EShapeGetRectangles(win, ShapeBounding, &rn, &ord);
if (rl)
{
if (rn < 1)
EShapeCombineMask(win, ShapeBounding, 0, 0, None, ShapeSet);
else if (rn == 1)
{
if ((rl[0].x == 0) && (rl[0].y == 0)
&& (rl[0].width == ww) && (rl[0].height == hh))
EShapeCombineMask(win, ShapeBounding, 0, 0,
None, ShapeSet);
}
Efree(rl);
}
else
EShapeCombineMask(win, ShapeBounding, 0, 0, None, ShapeSet);
}
XFree(list);
}

View File

@ -421,12 +421,7 @@ doMoveResizeEwin(EWin * ewin, int desk, int x, int y, int w, int h, int flags)
else
EoMoveResize(ewin, x, y, w, h);
if (raise)
{
EoSetFloating(ewin, floating);
RaiseEwin(ewin);
}
#if 1 /* FIXME - Should be done when shading/unshading */
if (ewin->shaded == 0)
{
EMoveResizeWindow(ewin->win_container,
@ -437,10 +432,21 @@ doMoveResizeEwin(EWin * ewin, int desk, int x, int y, int w, int h, int flags)
{
EMoveResizeWindow(ewin->win_container, -30, -30, 1, 1);
}
#endif
EMoveResizeWindow(ewin->client.win, 0, 0, ewin->client.w, ewin->client.h);
if (flags & MRF_RESIZE)
{
EMoveResizeWindow(ewin->client.win, 0, 0, ewin->client.w,
ewin->client.h);
EwinBorderCalcSizes(ewin, 0);
}
EwinPropagateShapes(ewin);
EwinBorderCalcSizes(ewin);
if (raise)
{
EoSetFloating(ewin, floating);
RaiseEwin(ewin);
}
if (Mode.mode == MODE_NONE || Conf.movres.update_while_moving)
ICCCM_Configure(ewin);
@ -797,7 +803,7 @@ EwinInstantShade(EWin * ewin, int force)
ewin->shaded = 2;
EoMoveResize(ewin, x, y, w, h);
EMoveResizeWindow(ewin->win_container, -30, -30, 1, 1);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
ESync();
HintsSetWindowState(ewin);
@ -901,7 +907,7 @@ EwinShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
w = i;
@ -921,7 +927,7 @@ EwinShade(EWin * ewin)
0, ewin->client.win, ShapeBounding,
ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -938,7 +944,7 @@ EwinShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
j = ((c * (1024 - k)) + (d * k)) >> 10;
@ -959,7 +965,7 @@ EwinShade(EWin * ewin)
ShapeBounding, 0, 0, ewin->client.win,
ShapeBounding, ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -975,7 +981,7 @@ EwinShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
h = i;
@ -996,7 +1002,7 @@ EwinShade(EWin * ewin)
ewin->client.win, ShapeBounding,
ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1014,7 +1020,7 @@ EwinShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
j = ((c * (1024 - k)) + (d * k)) >> 10;
@ -1035,7 +1041,7 @@ EwinShade(EWin * ewin)
ShapeBounding, 0, 0, ewin->client.win,
ShapeBounding, ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1049,7 +1055,9 @@ EwinShade(EWin * ewin)
if (ewin->client.shaped)
EShapeCombineShape(ewin->win_container, ShapeBounding, 0, 0,
ewin->client.win, ShapeBounding, ShapeSet);
MoveEwin(ewin, EoGetX(ewin), EoGetY(ewin));
MoveResizeEwin(ewin, EoGetX(ewin), EoGetY(ewin), ewin->client.w,
ewin->client.h);
ESync();
#if 0
@ -1105,7 +1113,7 @@ EwinUnShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
w = i;
@ -1124,7 +1132,7 @@ EwinUnShade(EWin * ewin)
ewin->client.win, ShapeBounding,
ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1151,7 +1159,7 @@ EwinUnShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
j = ((c * (1024 - k)) + (d * k)) >> 10;
@ -1167,7 +1175,7 @@ EwinUnShade(EWin * ewin)
ShapeBounding, 0, 0, ewin->client.win,
ShapeBounding, ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1192,7 +1200,7 @@ EwinUnShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
h = i;
@ -1211,7 +1219,7 @@ EwinUnShade(EWin * ewin)
ewin->client.win, ShapeBounding,
ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1238,7 +1246,7 @@ EwinUnShade(EWin * ewin)
if ((Conf.animate_shading) || (ewin->type == EWIN_TYPE_MENU))
{
ETimedLoopInit(0, 1024, speed);
for (k = 0; k <= 1024;)
for (k = 0; k < 1024;)
{
i = ((a * (1024 - k)) + (b * k)) >> 10;
j = ((c * (1024 - k)) + (d * k)) >> 10;
@ -1254,7 +1262,7 @@ EwinUnShade(EWin * ewin)
ShapeBounding, 0, 0, ewin->client.win,
ShapeBounding, ShapeSet);
EoMoveResize(ewin, x, y, w, h);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
k = ETimedLoopNext();
}
@ -1267,6 +1275,11 @@ EwinUnShade(EWin * ewin)
att.win_gravity = NorthWestGravity;
EChangeWindowAttributes(ewin->client.win, CWWinGravity, &att);
EMoveResizeWindow(ewin->client.win, 0, 0, ewin->client.w, ewin->client.h);
EMoveResizeWindow(ewin->win_container,
ewin->border->border.left,
ewin->border->border.top, ewin->client.w, ewin->client.h);
if (ewin->client.shaped)
EShapeCombineShape(ewin->win_container, ShapeBounding, 0, 0,
ewin->client.win, ShapeBounding, ShapeSet);

View File

@ -149,8 +149,6 @@ EwinCreate(Window win, int type)
ewin->client.event_mask = EWIN_CLIENT_EVENT_MASK;
AddItem(ewin, "EWIN", win, LIST_TYPE_EWIN);
XShapeSelectInput(disp, win, ShapeNotifyMask);
if (EventDebug(EDBUG_TYPE_EWINS))
Eprintf("EwinCreate %#lx frame=%#lx state=%d\n", ewin->client.win,
EoGetWin(ewin), ewin->state);
@ -163,6 +161,7 @@ EwinCreate(Window win, int type)
if (!EwinIsInternal(ewin))
{
XShapeSelectInput(disp, win, ShapeNotifyMask);
XSetWindowBorderWidth(disp, win, 0);
ewin->client.bw = 0;
}
@ -504,7 +503,7 @@ EwinPropagateShapes(EWin * ewin)
#endif
if (!ewin->shapedone)
{
PropagateShapes(EoGetWin(ewin));
EShapePropagate(EoGetWin(ewin));
EoChangeShape(ewin);
ewin->shapedone = 1;
}
@ -1164,7 +1163,7 @@ EwinEventConfigureRequest(EWin * ewin, XEvent * ev)
Mode.move.check = 0; /* Don't restrict client requests */
MoveResizeEwin(ewin, x, y, w, h);
Mode.move.check = 1;
#if 0 /* FIXME - Remove? */
{
char pshaped;
@ -1172,10 +1171,11 @@ EwinEventConfigureRequest(EWin * ewin, XEvent * ev)
ICCCM_GetShapeInfo(ewin);
if (pshaped != ewin->client.shaped)
{
SyncBorderToEwin(ewin);
ewin->shapedone = 0;
EwinPropagateShapes(ewin);
}
}
#endif
ReZoom(ewin);
}
else
@ -1204,6 +1204,7 @@ EwinEventResizeRequest(EWin * ewin, XEvent * ev)
w = ev->xresizerequest.width;
h = ev->xresizerequest.height;
ResizeEwin(ewin, w, h);
#if 0 /* FIXME - Remove? */
{
char pshaped;
@ -1211,10 +1212,11 @@ EwinEventResizeRequest(EWin * ewin, XEvent * ev)
ICCCM_GetShapeInfo(ewin);
if (pshaped != ewin->client.shaped)
{
SyncBorderToEwin(ewin);
ewin->shapedone = 0;
EwinPropagateShapes(ewin);
}
}
#endif
ReZoom(ewin);
}
else
@ -1254,7 +1256,6 @@ EwinEventPropertyNotify(EWin * ewin, XEvent * ev)
HintsProcessPropertyChange(ewin, ev->xproperty.atom);
SessionGetInfo(ewin, ev->xproperty.atom);
SyncBorderToEwin(ewin);
EwinChangesProcess(ewin);
EUngrabServer();
@ -1263,14 +1264,8 @@ EwinEventPropertyNotify(EWin * ewin, XEvent * ev)
static void
EwinEventShapeChange(EWin * ewin)
{
const Border *b;
b = ewin->border;
SyncBorderToEwin(ewin);
#if 0
if (ewin->border == b)
#endif
ewin->shapedone = 0;
ICCCM_GetShapeInfo(ewin);
ewin->shapedone = 0;
EwinPropagateShapes(ewin);
}
@ -1598,7 +1593,7 @@ EwinChangesProcess(EWin * ewin)
if (EWinChanges.flags & EWIN_CHANGE_NAME)
{
EwinBorderUpdateInfo(ewin);
EwinBorderCalcSizes(ewin);
EwinBorderCalcSizes(ewin, 1);
}
if (EWinChanges.flags & EWIN_CHANGE_DESKTOP)

View File

@ -765,46 +765,14 @@ ICCCM_GetHints(EWin * ewin, Atom atom_change)
void
ICCCM_GetShapeInfo(EWin * ewin)
{
XRectangle *rl = NULL;
int rn = 0, ord;
int x, y, w, h, d;
Window rt;
EGrabServer();
EGetGeometry(ewin->client.win, &rt, &x, &y, &w, &h, &d, &d);
rl = EShapeGetRectangles(ewin->client.win, ShapeBounding, &rn, &ord);
ewin->client.shaped = EShapeCopy(ewin->win_container, ewin->client.win);
EUngrabServer();
if (rn < 1)
{
ewin->client.shaped = 0;
EShapeCombineMask(ewin->win_container, ShapeBounding, 0, 0, None,
ShapeSet);
}
else if (rn == 1)
{
if ((rl[0].x <= 0) && (rl[0].y <= 0) && (rl[0].width >= w)
&& (rl[0].height >= h))
{
ewin->client.shaped = 0;
EShapeCombineMask(ewin->win_container, ShapeBounding, 0, 0,
None, ShapeSet);
}
else
{
ewin->client.shaped = 1;
EShapeCombineShape(ewin->win_container, ShapeBounding, 0, 0,
ewin->client.win, ShapeBounding, ShapeSet);
}
}
else
{
ewin->client.shaped = 1;
EShapeCombineShape(ewin->win_container, ShapeBounding, 0, 0,
ewin->client.win, ShapeBounding, ShapeSet);
}
if (rl)
XFree(rl);
#if 0 /* Debug */
Eprintf("ICCCM_GetShapeInfo %#lx cont=%#lx shaped=%d\n",
ewin->client.win, ewin->win_container, ewin->client.shaped);
#endif
}
void

View File

@ -1654,13 +1654,13 @@ IB_DrawScroll(Iconbox * ib)
}
#if 0 /* FIXME - Remove? */
PropagateShapes(ib->win);
EShapePropagate(ib->win);
if (ib->ewin)
{
const Border *b;
b = ib->ewin->border;
SyncBorderToEwin(ib->ewin);
ICCCM_GetShapeInfo(ib->ewin);
if (ib->ewin->border == b)
EwinPropagateShapes(ib->ewin);
}
@ -1918,14 +1918,14 @@ IconboxRedraw(Iconbox * ib)
EClearWindow(ib->icon_win);
if (ib->type == IB_TYPE_SYSTRAY && ib->nobg && !ib->draw_icon_base)
PropagateShapes(ib->icon_win);
EShapePropagate(ib->icon_win);
}
else
{
/* Transparent and no objects */
EUnmapWindow(ib->icon_win);
}
PropagateShapes(ib->win);
EShapePropagate(ib->win);
ICCCM_GetShapeInfo(ib->ewin);
ib->ewin->shapedone = 0;
EwinPropagateShapes(ib->ewin);

View File

@ -876,7 +876,7 @@ MenuRedraw(Menu * m)
{
for (i = 0; i < m->num; i++)
MenuDrawItem(m, m->items[i], 0);
PropagateShapes(m->win);
EShapePropagate(m->win);
}
}
@ -942,7 +942,7 @@ MenuDrawItem(Menu * m, MenuItem * mi, char shape)
EClearWindow(mi->win);
if ((shape) && (m->style->use_item_bg))
PropagateShapes(m->win);
EShapePropagate(m->win);
if (mi->state == STATE_HILITED)
{

View File

@ -315,7 +315,7 @@ SlideoutCalcSize(Slideout * s)
break;
}
}
PropagateShapes(s->win);
EShapePropagate(s->win);
}
static void

View File

@ -148,7 +148,7 @@ WarpFocusShow(EWin * ewin)
0, ST_WARPLIST);
}
PropagateShapes(warpFocusWindow->win);
EShapePropagate(warpFocusWindow->win);
EobjMap(warpFocusWindow, 0);
/*
@ -202,7 +202,7 @@ WarpFocusShow(EWin * ewin)
}
}
PropagateShapes(warpFocusWindow->win);
EShapePropagate(warpFocusWindow->win);
EFlush();
}

543
src/x.c
View File

@ -536,191 +536,6 @@ EUnmapWindow(Window win)
XUnmapWindow(disp, win);
}
void
EShapeCombineMask(Window win, int dest, int x, int y, Pixmap pmap, int op)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
{
char wasshaped = 0;
if (xid->rects)
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
wasshaped = 1;
}
if (pmap)
{
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
xid->rects =
XShapeGetRectangles(disp, win, dest, &(xid->num_rect),
&(xid->ord));
if (xid->rects)
{
if (xid->num_rect == 1)
{
if ((xid->rects[0].x == 0) && (xid->rects[0].y == 0)
&& (xid->rects[0].width == xid->w)
&& (xid->rects[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
}
}
}
}
else if ((!pmap) && (wasshaped))
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
}
else
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
}
void
EShapeCombineMaskTiled(Window win, int dest, int x, int y,
Pixmap pmap, int op, int w, int h)
{
XGCValues gcv;
GC gc;
Window tm;
gcv.fill_style = FillTiled;
gcv.tile = pmap;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
tm = ECreatePixmap(win, w, h, 1);
gc = ECreateGC(tm, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
XFillRectangle(disp, tm, gc, 0, 0, w, h);
EFreeGC(gc);
EShapeCombineMask(win, dest, x, y, tm, op);
EFreePixmap(tm);
}
void
EShapeCombineRectangles(Window win, int dest, int x, int y,
XRectangle * rect, int n_rects, int op, int ordering)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
{
if (n_rects == 1 && op == ShapeSet)
{
if ((rect[0].x == 0) && (rect[0].y == 0)
&& (rect[0].width == xid->w) && (rect[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
XShapeCombineMask(disp, win, dest, x, y, None, op);
return;
}
}
xid->num_rect = 0;
if (xid->rects)
XFree(xid->rects);
XShapeCombineRectangles(disp, win, dest, x, y, rect, n_rects, op,
ordering);
xid->rects =
XShapeGetRectangles(disp, win, dest, &(xid->num_rect), &(xid->ord));
if (xid->rects)
{
if (xid->num_rect == 1)
{
if ((xid->rects[0].x == 0) && (xid->rects[0].y == 0)
&& (xid->rects[0].width == xid->w)
&& (xid->rects[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
}
}
}
}
else
XShapeCombineRectangles(disp, win, dest, x, y, rect, n_rects, op,
ordering);
}
void
EShapeCombineShape(Window win, int dest, int x, int y,
Window src_win, int src_kind, int op)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
{
xid->num_rect = 0;
if (xid->rects)
XFree(xid->rects);
XShapeCombineShape(disp, win, dest, x, y, src_win, src_kind, op);
xid->rects =
XShapeGetRectangles(disp, win, dest, &(xid->num_rect), &(xid->ord));
if (xid->rects)
{
if (xid->num_rect == 1)
{
if ((xid->rects[0].x == 0) && (xid->rects[0].y == 0)
&& (xid->rects[0].width == xid->w)
&& (xid->rects[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
}
}
}
}
else
XShapeCombineShape(disp, win, dest, x, y, src_win, src_kind, op);
}
XRectangle *
EShapeGetRectangles(Window win, int dest, int *rn, int *ord)
{
EXID *xid;
xid = EXidFind(win);
if (xid && !xid->attached)
{
XRectangle *r;
*rn = xid->num_rect;
*ord = xid->ord;
if (xid->num_rect > 0)
{
r = Emalloc(sizeof(XRectangle) * xid->num_rect);
memcpy(r, xid->rects, sizeof(XRectangle) * xid->num_rect);
return r;
}
else
return NULL;
}
else
{
XRectangle *r, *rr;
r = XShapeGetRectangles(disp, win, dest, rn, ord);
if (r)
{
rr = Emalloc(sizeof(XRectangle) * *rn);
memcpy(rr, r, sizeof(XRectangle) * *rn);
XFree(r);
return rr;
}
}
return NULL;
}
void
EReparentWindow(Window win, Window parent, int x, int y)
{
@ -922,6 +737,364 @@ ESelectInputAdd(Window win, long mask)
XSelectInput(disp, win, xwa.your_event_mask);
}
#define DEBUG_SHAPE_OPS 0
#define DEBUG_SHAPE_PROPAGATE 0
#if DEBUG_SHAPE_OPS
static void
EShapeShow(const char *txt, XRectangle * pr, int nr)
{
int i;
Eprintf("%s nr=%d\n", txt, nr);
for (i = 0; i < nr; i++)
Eprintf(" %d - %4d,%4d %4dx%4d\n", i,
pr[i].x, pr[i].y, pr[i].width, pr[i].height);
}
#endif
static void
EXidShapeUpdate(EXID * xid)
{
if (xid->rects)
{
XFree(xid->rects);
xid->num_rect = 0;
}
xid->rects =
XShapeGetRectangles(disp, xid->win, ShapeBounding, &(xid->num_rect),
&(xid->ord));
if (xid->rects)
{
if (xid->num_rect == 1)
{
if ((xid->rects[0].x == 0) && (xid->rects[0].y == 0)
&& (xid->rects[0].width == xid->w)
&& (xid->rects[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
}
}
}
else
{
xid->num_rect = -1;
}
#if DEBUG_SHAPE_OPS
EShapeShow("EXidShapeUpdate", xid->rects, xid->num_rect);
#endif
}
void
EShapeCombineMask(Window win, int dest, int x, int y, Pixmap pmap, int op)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
{
char wasshaped = 0;
if (xid->rects)
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
wasshaped = 1;
}
#if DEBUG_SHAPE_OPS
Eprintf("EShapeCombineMask %#lx wassh=%d\n", win, wasshaped);
#endif
if (pmap)
{
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
EXidShapeUpdate(xid);
}
else if (wasshaped)
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
}
else
XShapeCombineMask(disp, win, dest, x, y, pmap, op);
}
void
EShapeCombineMaskTiled(Window win, int dest, int x, int y,
Pixmap pmap, int op, int w, int h)
{
XGCValues gcv;
GC gc;
Window tm;
gcv.fill_style = FillTiled;
gcv.tile = pmap;
gcv.ts_x_origin = 0;
gcv.ts_y_origin = 0;
tm = ECreatePixmap(win, w, h, 1);
gc = ECreateGC(tm, GCFillStyle | GCTile |
GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
XFillRectangle(disp, tm, gc, 0, 0, w, h);
EFreeGC(gc);
EShapeCombineMask(win, dest, x, y, tm, op);
EFreePixmap(tm);
}
void
EShapeCombineRectangles(Window win, int dest, int x, int y,
XRectangle * rect, int n_rects, int op, int ordering)
{
EXID *xid;
#if DEBUG_SHAPE_OPS
Eprintf("EShapeCombineRectangles %#lx %d\n", win, n_rects);
#endif
xid = EXidFind(win);
if (xid)
{
if (n_rects == 1 && op == ShapeSet)
{
if ((rect[0].x == 0) && (rect[0].y == 0) &&
(rect[0].width == xid->w) && (rect[0].height == xid->h))
{
xid->num_rect = 0;
XFree(xid->rects);
xid->rects = NULL;
XShapeCombineMask(disp, win, dest, x, y, None, op);
return;
}
}
XShapeCombineRectangles(disp, win, dest, x, y, rect, n_rects, op,
ordering);
if (n_rects > 1)
{
/* Limit shape to window extents */
XRectangle r;
r.x = r.y = 0;
r.width = xid->w;
r.height = xid->h;
XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &r,
1, ShapeIntersect, Unsorted);
}
EXidShapeUpdate(xid);
}
else
XShapeCombineRectangles(disp, win, dest, x, y, rect, n_rects, op,
ordering);
}
void
EShapeCombineShape(Window win, int dest, int x, int y,
Window src_win, int src_kind, int op)
{
EXID *xid;
xid = EXidFind(win);
if (xid)
{
XShapeCombineShape(disp, win, dest, x, y, src_win, src_kind, op);
EXidShapeUpdate(xid);
}
else
XShapeCombineShape(disp, win, dest, x, y, src_win, src_kind, op);
}
XRectangle *
EShapeGetRectangles(Window win, int dest, int *rn, int *ord)
{
EXID *xid;
xid = EXidFind(win);
if (xid && !xid->attached)
{
XRectangle *r;
#if DEBUG_SHAPE_OPS
Eprintf("EShapeGetRectangles-A %#lx nr=%d\n", win, xid->num_rect);
#endif
*rn = xid->num_rect;
*ord = xid->ord;
if (xid->num_rect > 0)
{
r = Emalloc(sizeof(XRectangle) * xid->num_rect);
memcpy(r, xid->rects, sizeof(XRectangle) * xid->num_rect);
return r;
}
}
else
{
XRectangle *r, *rr;
#if DEBUG_SHAPE_OPS
Eprintf("EShapeGetRectangles-B %#lx nr=%d\n", win, xid->num_rect);
#endif
r = XShapeGetRectangles(disp, win, dest, rn, ord);
if (r)
{
rr = Emalloc(sizeof(XRectangle) * *rn);
memcpy(rr, r, sizeof(XRectangle) * *rn);
XFree(r);
return rr;
}
}
return NULL;
}
int
EShapeCopy(Window dst, Window src)
{
XRectangle *rl;
int rn = 0, ord;
int x, y, w, h, d;
Window rt;
EGrabServer();
EGetGeometry(src, &rt, &x, &y, &w, &h, &d, &d);
rl = EShapeGetRectangles(src, ShapeBounding, &rn, &ord);
EUngrabServer();
if (rn < 0)
{
/* Source has empty shape */
EShapeCombineShape(dst, ShapeBounding, 0, 0,
src, ShapeBounding, ShapeSet);
}
else if (rn == 0)
{
/* Source has default shape (no shape) */
EShapeCombineMask(dst, ShapeBounding, 0, 0, None, ShapeSet);
}
else if (rn == 1)
{
if ((rl[0].x <= 0) && (rl[0].y <= 0) && (rl[0].width >= w)
&& (rl[0].height >= h))
{
rn = 0;
EShapeCombineMask(dst, ShapeBounding, 0, 0, None, ShapeSet);
}
else
{
EShapeCombineShape(dst, ShapeBounding, 0, 0,
src, ShapeBounding, ShapeSet);
}
}
else
{
EShapeCombineShape(dst, ShapeBounding, 0, 0,
src, ShapeBounding, ShapeSet);
}
if (rl)
XFree(rl);
return rn != 0;
}
void
EShapePropagate(Window win)
{
Window rt, par, *list = NULL;
unsigned int i, num, num_rects;
int k, rn, ord;
int x, y, w, h, xx, yy, ww, hh, d;
XRectangle *rects, *rl;
XWindowAttributes att;
if (!EGetGeometry(win, &rt, &xx, &yy, &ww, &hh, &d, &d))
return;
if ((ww <= 0) || (hh <= 0))
return;
#if DEBUG_SHAPE_PROPAGATE
Eprintf("EShapePropagate %#lx %d,%d %dx%d\n", win, xx, yy, ww, hh);
#endif
XQueryTree(disp, win, &rt, &par, &list, &num);
if (!list)
return;
num_rects = 0;
rects = NULL;
/* go through all child windows and create/inset spans */
for (i = 0; i < num; i++)
{
XGetWindowAttributes(disp, list[i], &att);
#if DEBUG_SHAPE_PROPAGATE > 1
Eprintf("%3d %#lx(%d): %4d,%4d %4dx%4d\n", i, list[i], att.map_state,
att.x, att.y, att.width, att.height);
#endif
if ((att.class != InputOutput) || (att.map_state == IsUnmapped))
continue;
x = att.x;
y = att.y;
w = att.width;
h = att.height;
if (x >= ww || y >= hh || x + w < 0 || y + h < 0)
continue;
rl = EShapeGetRectangles(list[i], ShapeBounding, &rn, &ord);
if (rn > 0)
{
rects = Erealloc(rects, (num_rects + rn) * sizeof(XRectangle));
/* go through all clip rects in thsi window's shape */
for (k = 0; k < rn; k++)
{
/* for each clip rect, add it to the rect list */
rects[num_rects + k].x = x + rl[k].x;
rects[num_rects + k].y = y + rl[k].y;
rects[num_rects + k].width = rl[k].width;
rects[num_rects + k].height = rl[k].height;
#if DEBUG_SHAPE_PROPAGATE > 1
Eprintf(" - %d: %4d,%4d %4dx%4d\n", k,
rects[num_rects + k].x,
rects[num_rects + k].y, rects[num_rects + k].width,
rects[num_rects + k].height);
#endif
}
num_rects += rn;
Efree(rl);
}
else if (rn == 0)
{
/* Unshaped */
rects = Erealloc(rects, (num_rects + 1) * sizeof(XRectangle));
rects[num_rects].x = x;
rects[num_rects].y = y;
rects[num_rects].width = w;
rects[num_rects].height = h;
num_rects++;
}
}
#if DEBUG_SHAPE_PROPAGATE > 1
Eprintf("EShapePropagate %#lx nr=%d\n", win, num_rects);
for (i = 0; i < num_rects; i++)
Eprintf("%3d %4d,%4d %4dx%4d\n", i, rects[i].x, rects[i].y,
rects[i].width, rects[i].height);
#endif
/* set the rects as the shape mask */
if (rects)
{
EShapeCombineRectangles(win, ShapeBounding, 0, 0, rects,
num_rects, ShapeSet, Unsorted);
Efree(rects);
}
else
{
/* Empty shape */
EShapeCombineRectangles(win, ShapeBounding, 0, 0, NULL, 0, ShapeSet,
Unsorted);
}
XFree(list);
}
GC
ECreateGC(Drawable d, unsigned long mask, XGCValues * val)
{