summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kasprzyk <onestone@compiz-fusion.org>2008-09-02 16:08:04 +0200
committerDennis kasprzyk <onestone@compiz-fusion.org>2008-09-02 16:08:04 +0200
commitb084c60246c9deeaa2de0b977ee7fd5d69bfe03a (patch)
tree1ee4d3d87d59d012d96a98f15e067f14e9341688
parent603ba6820e732dc8ba7219c54414dce24e38d781 (diff)
downloadzcomp-b084c60246c9deeaa2de0b977ee7fd5d69bfe03a.tar.gz
zcomp-b084c60246c9deeaa2de0b977ee7fd5d69bfe03a.tar.bz2
Reparent window instead of simple input frame window.
-rw-r--r--include/compdisplay.h2
-rw-r--r--include/compscreen.h2
-rw-r--r--include/compwindow.h12
-rw-r--r--plugins/composite/window.cpp33
-rw-r--r--plugins/decor.cpp2
-rw-r--r--plugins/opengl/screen.cpp1
-rw-r--r--plugins/opengl/window.cpp12
-rw-r--r--src/display.cpp4
-rw-r--r--src/event.cpp23
-rw-r--r--src/privatewindow.h4
-rw-r--r--src/screen.cpp30
-rw-r--r--src/window.cpp285
12 files changed, 312 insertions, 98 deletions
diff --git a/include/compdisplay.h b/include/compdisplay.h
index 7aace87..64f53cc 100644
--- a/include/compdisplay.h
+++ b/include/compdisplay.h
@@ -286,7 +286,7 @@ class CompDisplay :
findWindow (Window id);
CompWindow *
- findTopLevelWindow (Window id);
+ findTopLevelWindow (Window id, bool override_redirect = false);
diff --git a/include/compscreen.h b/include/compscreen.h
index dc38385..3bfe308 100644
--- a/include/compscreen.h
+++ b/include/compscreen.h
@@ -164,7 +164,7 @@ class CompScreen :
findWindow (Window id);
CompWindow *
- findTopLevelWindow (Window id);
+ findTopLevelWindow (Window id, bool override_redirect = false);
void
insertWindow (CompWindow *w, Window aboveId);
diff --git a/include/compwindow.h b/include/compwindow.h
index 4221578..8686fd3 100644
--- a/include/compwindow.h
+++ b/include/compwindow.h
@@ -24,6 +24,8 @@ struct CompStartupSequence;
#define GET_CORE_WINDOW(object) (dynamic_cast<CompWindow *> (object))
#define CORE_WINDOW(object) CompWindow *w = GET_CORE_WINDOW (object)
+#define ROOTPARENT(x) (((x)->frame ()) ? (x)->frame () : (x)->id ())
+
#define CompWindowProtocolDeleteMask (1 << 0)
#define CompWindowProtocolTakeFocusMask (1 << 1)
#define CompWindowProtocolPingMask (1 << 2)
@@ -186,7 +188,10 @@ enum CompWindowNotify {
CompWindowNotifyHide,
CompWindowNotifyShow,
CompWindowNotifyAliveChanged,
- CompWindowNotifySyncAlarm
+ CompWindowNotifySyncAlarm,
+ CompWindowNotifyReparent,
+ CompWindowNotifyUnreparent,
+ CompWindowNotifyFrameUpdate
};
struct CompWindowExtents {
@@ -276,6 +281,7 @@ class CompWindow :
Window id ();
Window frame ();
+ Window wrapper ();
Region region ();
@@ -423,8 +429,8 @@ class CompWindow :
void
sendSyncRequest ();
- void
- configure (XConfigureEvent *ce);
+ void configure (XConfigureEvent *ce);
+ void configureFrame (XConfigureEvent *ce);
void
circulate (XCirculateEvent *ce);
diff --git a/plugins/composite/window.cpp b/plugins/composite/window.cpp
index a7e3913..8dfb9ee 100644
--- a/plugins/composite/window.cpp
+++ b/plugins/composite/window.cpp
@@ -106,7 +106,7 @@ CompositeWindow::bind ()
is mapped when getting the window pixmap */
XGrabServer (priv->screen->display ()->dpy ());
XGetWindowAttributes (priv->screen->display ()->dpy (),
- priv->window->id (), &attr);
+ ROOTPARENT (priv->window), &attr);
if (attr.map_state != IsViewable)
{
XUngrabServer (priv->screen->display ()->dpy ());
@@ -115,7 +115,7 @@ CompositeWindow::bind ()
}
priv->pixmap = XCompositeNameWindowPixmap
- (priv->screen->display ()->dpy (), priv->window->id ());
+ (priv->screen->display ()->dpy (), ROOTPARENT (priv->window));
XUngrabServer (priv->screen->display ()->dpy ());
}
@@ -145,7 +145,7 @@ CompositeWindow::redirect ()
return;
XCompositeRedirectWindow (priv->screen->display ()->dpy (),
- priv->window->id (),
+ ROOTPARENT (priv->window),
CompositeRedirectManual);
priv->redirected = true;
@@ -171,7 +171,7 @@ CompositeWindow::unredirect ()
release ();
XCompositeUnredirectWindow (priv->screen->display ()->dpy (),
- priv->window->id (),
+ ROOTPARENT (priv->window),
CompositeRedirectManual);
priv->redirected = false;
@@ -313,13 +313,18 @@ CompositeWindow::addDamage (bool force)
{
BoxRec box;
- box.x1 = -priv->window->output ().left -
+ box.x1 = -MAX (priv->window->output ().left,
+ priv->window->input ().left) -
priv->window->attrib ().border_width;
- box.y1 = -priv->window->output ().top -
+ box.y1 = -MAX (priv->window->output ().top,
+ priv->window->input ().top) -
priv->window->attrib ().border_width;
box.x2 = priv->window->width () +
- priv->window->output ().right;
- box.y2 = priv->window->height () + priv->window->output ().bottom;
+ MAX (priv->window->output ().right,
+ priv->window->input ().right);
+ box.y2 = priv->window->height () +
+ MAX (priv->window->output ().bottom,
+ priv->window->input ().bottom);
addDamageRect (&box);
}
@@ -497,6 +502,18 @@ PrivateCompositeWindow::windowNotify (CompWindowNotify n)
case CompWindowNotifyAliveChanged:
cWindow->addDamage (true);
break;
+ case CompWindowNotifyReparent:
+ case CompWindowNotifyUnreparent:
+ if (redirected)
+ {
+ cWindow->release ();
+ }
+ cScreen->damageScreen ();
+ cWindow->addDamage (true);
+ break;
+ case CompWindowNotifyFrameUpdate:
+ cWindow->release ();
+ break;
case CompWindowNotifySyncAlarm:
{
XRectangle *rects;
diff --git a/plugins/decor.cpp b/plugins/decor.cpp
index 4ee7cf3..d671a3a 100644
--- a/plugins/decor.cpp
+++ b/plugins/decor.cpp
@@ -1081,7 +1081,7 @@ DecorDisplay::handleEvent (XEvent *event)
XShapeGetRectangles (display->dpy (),
dw->inputFrame, ShapeInput,
&n, &order);
- if (!n)
+ if (!n || !shapeRects)
break;
for (int i = 0; i < n; i++)
diff --git a/plugins/opengl/screen.cpp b/plugins/opengl/screen.cpp
index aa8da96..62b4e51 100644
--- a/plugins/opengl/screen.cpp
+++ b/plugins/opengl/screen.cpp
@@ -491,7 +491,6 @@ GLScreen::GLScreen (CompScreen *s) :
priv->filter[SCREEN_TRANS_FILTER] = GLTexture::Good;
priv->filter[WINDOW_TRANS_FILTER] = GLTexture::Good;
-
if (!CompositeScreen::get (s)->registerPaintHandler (priv))
setFailed ();
diff --git a/plugins/opengl/window.cpp b/plugins/opengl/window.cpp
index 4bb5e87..9be1d37 100644
--- a/plugins/opengl/window.cpp
+++ b/plugins/opengl/window.cpp
@@ -53,20 +53,21 @@ void
PrivateGLWindow::setWindowMatrix ()
{
matrix = texture.matrix ();
- matrix.x0 -= (window->attrib ().x * matrix.xx);
- matrix.y0 -= (window->attrib ().y * matrix.yy);
+ matrix.x0 -= ((window->attrib ().x - window->input ().left) * matrix.xx);
+ matrix.y0 -= ((window->attrib ().y - window->input ().top) * matrix.yy);
}
bool
GLWindow::bind ()
{
+ CompWindowExtents i = priv->window->input ();
if (!priv->cWindow->pixmap () && !priv->cWindow->bind ())
return false;
if (!priv->texture.bindPixmap (priv->cWindow->pixmap (),
- priv->window->width (),
- priv->window->height (),
+ priv->window->width () + i.left + i.right,
+ priv->window->height () + i.top + i.bottom,
priv->window->attrib ().depth))
{
compLogMessage (priv->screen->display (), "opengl", CompLogLevelInfo,
@@ -153,6 +154,9 @@ PrivateGLWindow::windowNotify (CompWindowNotify n)
switch (n)
{
case CompWindowNotifyUnmap:
+ case CompWindowNotifyReparent:
+ case CompWindowNotifyUnreparent:
+ case CompWindowNotifyFrameUpdate:
gWindow->release ();
break;
case CompWindowNotifyAliveChanged:
diff --git a/src/display.cpp b/src/display.cpp
index 946f314..71896d2 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -1435,13 +1435,13 @@ CompDisplay::findWindow (Window id)
}
CompWindow *
-CompDisplay::findTopLevelWindow (Window id)
+CompDisplay::findTopLevelWindow (Window id, bool override_redirect)
{
CompWindow *w;
foreach (CompScreen *s, priv->screens)
{
- w = s->findTopLevelWindow (id);
+ w = s->findTopLevelWindow (id, override_redirect);
if (w)
return w;
}
diff --git a/src/event.cpp b/src/event.cpp
index fdde380..8824235 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -1012,20 +1012,31 @@ CompDisplay::handleEvent (XEvent *event)
break;
case ConfigureNotify:
w = findWindow (event->xconfigure.window);
- if (w)
+ if (w && !w->frame ())
{
w->configure (&event->xconfigure);
}
else
{
- s = findScreen (event->xconfigure.window);
- if (s)
- s->configure (&event->xconfigure);
+ w = findTopLevelWindow (event->xconfigure.window);
+
+ if (w && w->frame () == event->xconfigure.window)
+ {
+ w->configureFrame (&event->xconfigure);
+ }
+ else
+ {
+ s = findScreen (event->xconfigure.window);
+ if (s)
+ s->configure (&event->xconfigure);
+ }
}
break;
case CreateNotify:
s = findScreen (event->xcreatewindow.parent);
- if (s)
+ w = findTopLevelWindow (event->xcreatewindow.window, true);
+
+ if (s && (!w || w->frame () != event->xcreatewindow.window))
{
new CompWindow (s, event->xcreatewindow.window,
s->getTopWindow ());
@@ -1098,7 +1109,7 @@ CompDisplay::handleEvent (XEvent *event)
{
new CompWindow (s, event->xreparent.window, s->getTopWindow ());
}
- else if (w)
+ else if (w && !s && event->xreparent.parent != w->wrapper ())
{
/* This is the only case where a window is removed but not
destroyed. We must remove our event mask and all passive
diff --git a/src/privatewindow.h b/src/privatewindow.h
index b5d1b17..2722c3a 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -134,6 +134,9 @@ class PrivateWindow {
int width,
int height);
+ bool reparent ();
+ void unreparent ();
+
public:
CompWindow *window;
@@ -142,6 +145,7 @@ class PrivateWindow {
int refcnt;
Window id;
Window frame;
+ Window wrapper;
unsigned int mapNum;
unsigned int activeNum;
XWindowAttributes attrib;
diff --git a/src/screen.cpp b/src/screen.cpp
index b60fc46..c855ef4 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -1405,28 +1405,30 @@ CompScreen::findWindow (Window id)
}
CompWindow *
-CompScreen::findTopLevelWindow (Window id)
+CompScreen::findTopLevelWindow (Window id, bool override_redirect)
{
CompWindow *w;
w = findWindow (id);
- if (!w)
- return NULL;
- if (w->attrib ().override_redirect)
+ if (w)
{
- /* likely a frame window */
- if (w->attrib ().c_class == InputOnly)
+ if (w->attrib ().override_redirect && !override_redirect)
+ return NULL;
+ else
+ return w;
+ }
+
+ foreach (CompWindow *w, priv->windows)
+ if (w->frame () == id)
{
- foreach (w, priv->windows)
- if (w->frame () == id)
- return w;
+ if (w->attrib ().override_redirect && !override_redirect)
+ return NULL;
+ else
+ return w;
}
- return NULL;
- }
-
- return w;
+ return NULL;
}
void
@@ -1451,7 +1453,7 @@ CompScreen::insertWindow (CompWindow *w, Window aboveId)
while (it != priv->windows.end ())
{
- if ((*it)->id () == aboveId)
+ if ((*it)->id () == aboveId || ((*it)->frame () && (*it)->frame () == aboveId))
break;
it++;
}
diff --git a/src/window.cpp b/src/window.cpp
index 4cba99b..5a442b7 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -687,49 +687,24 @@ PrivateWindow::updateFrameWindow ()
height = input.top + input.bottom;
if (!frame)
- {
- XSetWindowAttributes attr;
- XWindowChanges xwc;
-
- attr.event_mask = 0;
- attr.override_redirect = TRUE;
-
- frame = XCreateWindow (d->dpy (), screen->root (),
- x, y, width, height, 0,
- CopyFromParent,
- InputOnly,
- CopyFromParent,
- CWOverrideRedirect | CWEventMask, &attr);
-
- XGrabButton (d->dpy (), AnyButton, AnyModifier, frame, TRUE,
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
- GrabModeSync, GrabModeSync, None, None);
-
- xwc.stack_mode = Below;
- xwc.sibling = id;
-
- XConfigureWindow (d->dpy (), frame,
- CWSibling | CWStackMode, &xwc);
-
- if (mapNum || shaded)
- XMapWindow (d->dpy (), frame);
-
- XChangeProperty (d->dpy (), id, d->atoms ().frameWindow,
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &frame, 1);
- }
+ reparent ();
XMoveResizeWindow (d->dpy (), frame, x, y, width, height);
+ XMoveResizeWindow (d->dpy (), wrapper, input.left, input.top,
+ serverGeometry.width (), serverGeometry.height ());
+ XMoveResizeWindow (d->dpy (), id, 0, 0,
+ serverGeometry.width (), serverGeometry.height ());
+ window->sendConfigureNotify ();
- XShapeCombineRegion (d->dpy (), frame, ShapeInput,
+ XShapeCombineRegion (d->dpy (), frame, ShapeBounding,
-x, -y, frameRegion, ShapeSet);
+ window->windowNotify (CompWindowNotifyFrameUpdate);
}
else
{
if (frame)
{
- XDeleteProperty (d->dpy (), id, d->atoms ().frameWindow);
- XDestroyWindow (d->dpy (), frame);
+ unreparent ();
frame = None;
XSubtractRegion (&emptyRegion, &emptyRegion, frameRegion);
}
@@ -1088,6 +1063,9 @@ CompWindow::destroy ()
if (priv->destroyRefCnt)
return;
+ if (priv->frame)
+ priv->unreparent ();
+
if (!priv->destroyed)
{
priv->destroyed = true;
@@ -1180,7 +1158,10 @@ CompWindow::map ()
updateSize ();
if (priv->frame)
+ {
XMapWindow (priv->screen->display ()->dpy (), priv->frame);
+ XMapWindow (priv->screen->display ()->dpy (), priv->wrapper);
+ }
priv->screen->updateClientList ();
@@ -1208,12 +1189,7 @@ void
CompWindow::unmap ()
{
if (priv->mapNum)
- {
- if (priv->frame && !priv->shaded)
- XUnmapWindow (priv->screen->display ()->dpy (), priv->frame);
-
priv->mapNum = 0;
- }
priv->unmapRefCnt--;
if (priv->unmapRefCnt > 0)
@@ -1248,12 +1224,16 @@ PrivateWindow::restack (Window aboveId)
{
if (window->prev)
{
- if (aboveId && aboveId == window->prev->id ())
+ if (aboveId && (aboveId == window->prev->id () ||
+ aboveId == window->prev->frame ()))
return false;
}
else if (aboveId == None && !window->next)
return false;
+ if (aboveId && !screen->findTopLevelWindow (aboveId))
+ return false;
+
screen->unhookWindow (window);
screen->insertWindow (window, aboveId);
@@ -1327,11 +1307,6 @@ CompWindow::resize (CompWindow::Geometry gm)
dy = gm.y () - priv->attrib.y;
move (dx, dy, true, true);
-
- if (priv->frame)
- XMoveWindow (priv->screen->display ()->dpy (), priv->frame,
- priv->attrib.x - priv->input.left,
- priv->attrib.y - priv->input.top);
}
return true;
@@ -1456,6 +1431,11 @@ CompWindow::sendSyncRequest ()
void
CompWindow::configure (XConfigureEvent *ce)
{
+ if (priv->frame)
+ return;
+
+ priv->attrib.override_redirect = ce->override_redirect;
+
if (priv->syncWait)
{
priv->syncGeometry.set (ce->x, ce->y, ce->width, ce->height,
@@ -1472,7 +1452,37 @@ CompWindow::configure (XConfigureEvent *ce)
resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
}
- priv->attrib.override_redirect = ce->override_redirect;
+ if (ce->event == priv->screen->root ())
+ priv->restack (ce->above);
+}
+
+void
+CompWindow::configureFrame (XConfigureEvent *ce)
+{
+ int x, y, width, height;
+
+ if (!priv->frame)
+ return;
+
+ x = ce->x + priv->input.left;
+ y = ce->y + priv->input.top;
+ width = ce->width - priv->input.left - priv->input.right;
+ height = ce->height - priv->input.top - priv->input.bottom;
+
+
+ if (priv->syncWait)
+ {
+ priv->syncGeometry.set (x, y, width, height, ce->border_width);
+ }
+ else
+ {
+ if (ce->override_redirect)
+ {
+ priv->serverGeometry.set (x, y, width, height, ce->border_width);
+ }
+
+ resize (x, y, width, height, ce->border_width);
+ }
priv->restack (ce->above);
}
@@ -1512,13 +1522,16 @@ CompWindow::syncPosition ()
priv->serverGeometry.setX (priv->attrib.x);
priv->serverGeometry.setY (priv->attrib.y);
- XMoveWindow (priv->screen->display ()->dpy (), priv->id,
- priv->attrib.x, priv->attrib.y);
+ XMoveWindow (priv->screen->display ()->dpy (), ROOTPARENT (this),
+ priv->attrib.x - priv->input.left,
+ priv->attrib.y - priv->input.top);
if (priv->frame)
- XMoveWindow (priv->screen->display ()->dpy (), priv->frame,
- priv->serverGeometry.x () - priv->input.left,
- priv->serverGeometry.y () - priv->input.top);
+ {
+ XMoveWindow (priv->screen->display ()->dpy (), priv->wrapper,
+ priv->input.left, priv->input.top);
+ sendConfigureNotify ();
+ }
}
bool
@@ -2131,11 +2144,25 @@ PrivateWindow::reconfigureXWindow (unsigned int valueMask,
if (valueMask & CWBorderWidth)
serverGeometry.setBorder (xwc->border_width);
- XConfigureWindow (screen->display ()->dpy (), id, valueMask, xwc);
-
- if (frame && (valueMask & (CWSibling | CWStackMode)))
+ if (frame)
+ {
+ XWindowChanges wc = *xwc;
+ wc.x -= input.left;
+ wc.y -= input.top;
+ wc.width += input.left + input.right;
+ wc.height += input.top + input.bottom;
XConfigureWindow (screen->display ()->dpy (), frame,
- valueMask & (CWSibling | CWStackMode), xwc);
+ valueMask, &wc);
+ valueMask &= ~(CWSibling | CWStackMode);
+ xwc->x = input.left;
+ xwc->y = input.top;
+ XConfigureWindow (screen->display ()->dpy (), wrapper,
+ valueMask, xwc);
+ xwc->x = 0;
+ xwc->y = 0;
+ }
+
+ XConfigureWindow (screen->display ()->dpy (), id, valueMask, xwc);
}
bool
@@ -2726,7 +2753,7 @@ PrivateWindow::addWindowStackChanges (XWindowChanges *xwc,
mask |= CWSibling | CWStackMode;
xwc->stack_mode = Above;
- xwc->sibling = sibling->priv->id;
+ xwc->sibling = ROOTPARENT (sibling);
}
}
else if (sibling)
@@ -2734,7 +2761,7 @@ PrivateWindow::addWindowStackChanges (XWindowChanges *xwc,
mask |= CWSibling | CWStackMode;
xwc->stack_mode = Above;
- xwc->sibling = sibling->priv->id;
+ xwc->sibling = ROOTPARENT (sibling);
}
}
@@ -3215,6 +3242,9 @@ CompWindow::hide ()
priv->pendingUnmaps++;
+ if (priv->frame && !priv->shaded)
+ XUnmapWindow (priv->screen->display ()->dpy (), priv->frame);
+
XUnmapWindow (priv->screen->display ()->dpy (), priv->id);
if (priv->minimized || priv->inShowDesktopMode ||
@@ -4132,6 +4162,13 @@ CompWindow::frame ()
return priv->frame;
}
+Window
+CompWindow::wrapper ()
+{
+ return priv->wrapper;
+}
+
+
int
CompWindow::mapNum ()
{
@@ -4582,6 +4619,9 @@ CompWindow::~CompWindow ()
{
CompDisplay *d = priv->screen->display ();
+ if (priv->frame)
+ priv->unreparent ();
+
/* restore saved geometry and map if hidden */
if (!priv->attrib.override_redirect)
{
@@ -4628,6 +4668,7 @@ PrivateWindow::PrivateWindow (CompWindow *window, CompScreen *screen) :
refcnt (1),
id (None),
frame (None),
+ wrapper (None),
mapNum (0),
activeNum (0),
transientFor (None),
@@ -4806,9 +4847,15 @@ CompWindow::updateFrameRegion ()
r.extents.y2 += priv->input.bottom;
XIntersectRegion (priv->frameRegion, &r, priv->frameRegion);
+
+ XUnionRegion (priv->frameRegion, priv->region, priv->frameRegion);
priv->updateFrameWindow ();
}
+ else if (priv->frame)
+ {
+ priv->updateFrameWindow ();
+ }
}
void
@@ -4842,3 +4889,127 @@ CompWindow::setWindowFrameExtents (CompWindowExtents *i)
void
CompWindow::updateFrameRegion (Region region)
WRAPABLE_HND_FUNC(12, updateFrameRegion, region)
+
+bool
+PrivateWindow::reparent ()
+{
+ XSetWindowAttributes attr;
+ XWindowChanges xwc;
+ int mask;
+ XEvent e;
+
+ Display *dpy = screen->display ()->dpy ();
+
+ if (frame)
+ return false;
+
+ XSync (dpy, FALSE);
+
+ if (XCheckTypedWindowEvent (dpy, id, DestroyNotify, &e))
+ {
+ XPutBackEvent (dpy, &e);
+ return false;
+ }
+
+ mask = CWOverrideRedirect | CWEventMask | CWColormap | CWBackPixmap;
+
+ attr.background_pixmap = None;
+ attr.border_pixel = 0;
+ mask |= CWBorderPixel;
+ attr.colormap = attrib.colormap;
+ attr.override_redirect = TRUE;
+ attr.event_mask = SubstructureRedirectMask | StructureNotifyMask |
+ SubstructureNotifyMask | EnterWindowMask |
+ LeaveWindowMask;
+
+ frame = XCreateWindow(dpy, screen->root (), attrib.x - input.left,
+ attrib.y - input.top,
+ attrib.width + input.left + input.right,
+ attrib.height + input.top + input.bottom,
+ 0, attrib.depth,
+ InputOutput, attrib.visual, mask, &attr);
+
+ wrapper = XCreateWindow(dpy, frame, input.left, input.top,
+ attrib.width, attrib.height, 0, attrib.depth,
+ InputOutput, attrib.visual, mask, &attr);
+
+ attr.event_mask = PropertyChangeMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask;
+ attr.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask;
+
+ XGrabButton (dpy, AnyButton, AnyModifier, frame, TRUE,
+ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
+ GrabModeSync, GrabModeSync, None, None);
+
+ xwc.stack_mode = Below;
+ xwc.sibling = id;
+
+ XConfigureWindow (dpy, frame, CWSibling | CWStackMode, &xwc);
+
+ XMapWindow (dpy, wrapper);
+
+ XReparentWindow (dpy, id, wrapper, 0, 0);
+ XChangeSaveSet (dpy, id, SetModeInsert);
+ XFlush (dpy);
+
+ XChangeWindowAttributes(dpy, id, CWEventMask | CWDontPropagate, &attr);
+
+
+ if (mapNum || shaded)
+ {
+ XMapWindow (dpy, frame);
+ pendingUnmaps++;
+ pendingMaps++;
+ }
+
+ window->windowNotify (CompWindowNotifyReparent);
+
+ return true;
+}
+
+void
+PrivateWindow::unreparent ()
+{
+ Display *dpy = screen->display ()->dpy ();
+ XEvent e;
+ XWindowChanges xwc;
+
+ bool alive = true;
+
+ if (!frame)
+ return;
+
+ XSync (dpy, FALSE);
+
+ if (XCheckTypedWindowEvent (dpy, id, DestroyNotify, &e))
+ {
+ XPutBackEvent (dpy, &e);
+ alive = false;
+ }
+
+ if ((!destroyed) && alive)
+ {
+ XChangeSaveSet (dpy, id, SetModeDelete);
+ XSelectInput (dpy, frame, NoEventMask);
+ XReparentWindow (dpy, id, screen->root (), attrib.x, attrib.y);
+ xwc.stack_mode = Above;
+ xwc.sibling = frame;
+ XConfigureWindow (dpy, id, CWSibling | CWStackMode, &xwc);
+ XUnmapWindow (dpy, frame);
+ XFlush (dpy);
+
+ if (mapNum || shaded)
+ {
+ pendingUnmaps++;
+ pendingMaps++;
+ }
+ }
+
+ XDestroyWindow (dpy, frame);
+ XDestroyWindow (dpy, wrapper);
+ wrapper = None;
+ frame = None;
+
+ window->windowNotify (CompWindowNotifyUnreparent);
+}