summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/compwindow.h27
-rw-r--r--plugins/decor.cpp142
-rw-r--r--plugins/decor.h3
-rw-r--r--src/privatewindow.h4
-rw-r--r--src/window.cpp150
5 files changed, 208 insertions, 118 deletions
diff --git a/include/compwindow.h b/include/compwindow.h
index 09ffa4e..4221578 100644
--- a/include/compwindow.h
+++ b/include/compwindow.h
@@ -226,10 +226,12 @@ class WindowInterface : public WrapableInterface<CompWindow, WindowInterface> {
virtual void ungrabNotify ();
virtual void stateChangeNotify (unsigned int lastState);
+
+ virtual void updateFrameRegion (Region region);
};
class CompWindow :
- public WrapableHandler<WindowInterface, 12>,
+ public WrapableHandler<WindowInterface, 13>,
public CompObject
{
@@ -271,11 +273,16 @@ class CompWindow :
CompScreen *
screen ();
- Window
- id ();
+ Window id ();
- Window
- frame ();
+ Window frame ();
+
+ Region region ();
+
+ Region frameRegion ();
+
+ void updateFrameRegion ();
+ void setWindowFrameExtents (CompWindowExtents *input);
unsigned int &
wmType ();
@@ -304,11 +311,6 @@ class CompWindow :
void
handlePing (int lastPing);
-
-
- Region
- region ();
-
bool
inShowDesktopMode ();
@@ -385,9 +387,6 @@ class CompWindow :
recalcType ();
void
- setWindowFrameExtents (CompWindowExtents *input);
-
- void
updateWindowOutputExtents ();
void
@@ -629,6 +628,8 @@ class CompWindow :
WRAPABLE_HND (11, WindowInterface, void, stateChangeNotify,
unsigned int);
+ WRAPABLE_HND (12, WindowInterface, void, updateFrameRegion, Region);
+
friend class PrivateWindow;
private:
diff --git a/plugins/decor.cpp b/plugins/decor.cpp
index f1c8294..4ee7cf3 100644
--- a/plugins/decor.cpp
+++ b/plugins/decor.cpp
@@ -646,9 +646,9 @@ DecorWindow::update (bool allowDecoration)
return false;
if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE)
- window->setWindowFrameExtents (&decor->maxInput);
+ window->setWindowFrameExtents (&wd->decor->maxInput);
else
- window->setWindowFrameExtents (&decor->input);
+ window->setWindowFrameExtents (&wd->decor->input);
moveDx = shiftX () - oldShiftX;
moveDy = shiftY () - oldShiftY;
@@ -660,12 +660,12 @@ DecorWindow::update (bool allowDecoration)
}
else
{
- CompWindowExtents emptyInput;
+ CompWindowExtents emptyExtents;
+ wd = NULL;
- memset (&emptyInput, 0, sizeof (emptyInput));
- window->setWindowFrameExtents (&emptyInput);
+ memset (&emptyExtents, 0, sizeof (CompWindowExtents));
- wd = NULL;
+ window->setWindowFrameExtents (&emptyExtents);
moveDx = -oldShiftX;
moveDy = -oldShiftY;
@@ -753,45 +753,54 @@ DecorWindow::updateFrame ()
XChangeProperty (display->dpy (), window->id (),
dDisplay->inputFrameAtom, XA_WINDOW, 32,
PropModeReplace, (unsigned char *) &inputFrame, 1);
+
+ if (display->XShape ())
+ XShapeSelectInput (display->dpy (), inputFrame,
+ ShapeNotifyMask);
}
XMoveResizeWindow (display->dpy (), inputFrame, x, y, width, height);
XLowerWindow (display->dpy (), inputFrame);
- rects[i].x = 0;
- rects[i].y = 0;
- rects[i].width = width;
- rects[i].height = input.top;
+ if (!REGION_NOT_EMPTY (frameRegion))
+ {
+ rects[i].x = 0;
+ rects[i].y = 0;
+ rects[i].width = width;
+ rects[i].height = input.top;
+
+ if (rects[i].width && rects[i].height)
+ i++;
- if (rects[i].width && rects[i].height)
- i++;
+ rects[i].x = 0;
+ rects[i].y = input.top;
+ rects[i].width = input.left;
+ rects[i].height = height - input.top - input.bottom;
- rects[i].x = 0;
- rects[i].y = input.top;
- rects[i].width = input.left;
- rects[i].height = height - input.top - input.bottom;
+ if (rects[i].width && rects[i].height)
+ i++;
- if (rects[i].width && rects[i].height)
- i++;
+ rects[i].x = width - input.right;
+ rects[i].y = input.top;
+ rects[i].width = input.right;
+ rects[i].height = height - input.top - input.bottom;
- rects[i].x = width - input.right;
- rects[i].y = input.top;
- rects[i].width = input.right;
- rects[i].height = height - input.top - input.bottom;
+ if (rects[i].width && rects[i].height)
+ i++;
- if (rects[i].width && rects[i].height)
- i++;
+ rects[i].x = 0;
+ rects[i].y = height - input.bottom;
+ rects[i].width = width;
+ rects[i].height = input.bottom;
- rects[i].x = 0;
- rects[i].y = height - input.bottom;
- rects[i].width = width;
- rects[i].height = input.bottom;
+ if (rects[i].width && rects[i].height)
+ i++;
- if (rects[i].width && rects[i].height)
- i++;
+ XShapeCombineRectangles (display->dpy (), inputFrame, ShapeInput,
+ 0, 0, rects, i, ShapeSet, YXBanded);
- XShapeCombineRectangles (display->dpy (), inputFrame, ShapeInput,
- 0, 0, rects, i, ShapeSet, YXBanded);
+ EMPTY_REGION (frameRegion);
+ }
}
else
{
@@ -801,6 +810,7 @@ DecorWindow::updateFrame ()
dDisplay->inputFrameAtom);
XDestroyWindow (display->dpy (), inputFrame);
inputFrame = None;
+ EMPTY_REGION (frameRegion);
}
}
}
@@ -881,6 +891,30 @@ DecorScreen::checkForDm (bool updateWindows)
}
void
+DecorWindow::updateFrameRegion (Region region)
+{
+ window->updateFrameRegion (region);
+ if (wd)
+ {
+ if (REGION_NOT_EMPTY (frameRegion))
+ {
+ XOffsetRegion (frameRegion,
+ window->attrib ().x - window->input ().left,
+ window->attrib ().y - window->input ().top);
+ XUnionRegion (frameRegion, region, region);
+ XOffsetRegion (frameRegion,
+ - (window->attrib ().x - window->input ().left),
+ - (window->attrib ().y - window->input ().top));
+ }
+ else
+ {
+ XUnionRegion (&infiniteRegion, region, region);
+ }
+ }
+
+}
+
+void
DecorDisplay::handleEvent (XEvent *event)
{
Window activeWindow = display->activeWindow ();
@@ -946,7 +980,7 @@ DecorDisplay::handleEvent (XEvent *event)
}
switch (event->type) {
- case PropertyNotify:
+ case PropertyNotify:
if (event->xproperty.atom == winDecorAtom)
{
w = display->findWindow (event->xproperty.window);
@@ -1029,6 +1063,38 @@ DecorDisplay::handleEvent (XEvent *event)
w = display->findWindow (((XShapeEvent *) event)->window);
if (w)
DecorWindow::get (w)->update (true);
+ else
+ {
+ foreach (CompScreen *s, display->screens ())
+ foreach (w, s->windows ())
+ {
+ DECOR_WINDOW (w);
+ if (dw->inputFrame ==
+ ((XShapeEvent *) event)->window)
+ {
+ XRectangle *shapeRects = 0;
+ int order, n;
+
+ EMPTY_REGION (dw->frameRegion);
+
+ shapeRects =
+ XShapeGetRectangles (display->dpy (),
+ dw->inputFrame, ShapeInput,
+ &n, &order);
+ if (!n)
+ break;
+
+ for (int i = 0; i < n; i++)
+ XUnionRectWithRegion (&shapeRects[i],
+ dw->frameRegion,
+ dw->frameRegion);
+
+ w->updateFrameRegion ();
+
+ XFree (shapeRects);
+ }
+ }
+ }
}
break;
}
@@ -1166,6 +1232,7 @@ DecorWindow::stateChangeNotify (unsigned int lastState)
window->setWindowFrameExtents (&wd->decor->maxInput);
else
window->setWindowFrameExtents (&wd->decor->input);
+
updateFrame ();
}
}
@@ -1296,6 +1363,12 @@ DecorWindow::DecorWindow (CompWindow *w) :
decor (NULL),
inputFrame (None)
{
+ frameRegion = XCreateRegion ();
+ if (!frameRegion)
+ {
+ setFailed ();
+ return;
+ }
if (!w->attrib ().override_redirect)
updateDecoration ();
@@ -1312,6 +1385,9 @@ DecorWindow::DecorWindow (CompWindow *w) :
DecorWindow::~DecorWindow ()
{
+ if (frameRegion)
+ XDestroyRegion (frameRegion);
+
if (!window->destroyed ())
update (false);
diff --git a/plugins/decor.h b/plugins/decor.h
index d313443..6f55286 100644
--- a/plugins/decor.h
+++ b/plugins/decor.h
@@ -183,6 +183,7 @@ class DecorWindow :
void resizeNotify (int, int, int, int);
void moveNotify (int, int, bool);
void stateChangeNotify (unsigned int);
+ void updateFrameRegion (Region region);
bool damageRect (bool, BoxPtr);
@@ -218,6 +219,8 @@ class DecorWindow :
WindowDecoration *wd;
Decoration *decor;
+ Region frameRegion;
+
Window inputFrame;
CompCore::Timer resizeUpdate;
diff --git a/src/privatewindow.h b/src/privatewindow.h
index 1111f4e..b5d1b17 100644
--- a/src/privatewindow.h
+++ b/src/privatewindow.h
@@ -134,7 +134,6 @@ class PrivateWindow {
int width,
int height);
-
public:
CompWindow *window;
@@ -155,7 +154,8 @@ class PrivateWindow {
bool alpha;
int width;
int height;
- Region region;
+ Region region;
+ Region frameRegion;
unsigned int wmType;
unsigned int type;
diff --git a/src/window.cpp b/src/window.cpp
index 96357fc..4cba99b 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -675,9 +675,7 @@ PrivateWindow::updateFrameWindow ()
if (input.left || input.right || input.top || input.bottom)
{
- XRectangle rects[4];
int x, y, width, height;
- int i = 0;
int bw = serverGeometry.border () * 2;
x = serverGeometry.x () - input.left;
@@ -723,47 +721,8 @@ PrivateWindow::updateFrameWindow ()
XMoveResizeWindow (d->dpy (), frame, x, y, width, height);
- rects[i].x = 0;
- rects[i].y = 0;
- rects[i].width = width;
- rects[i].height = input.top;
-
- if (rects[i].width && rects[i].height)
- i++;
-
- rects[i].x = 0;
- rects[i].y = input.top;
- rects[i].width = input.left;
- rects[i].height = height - input.top - input.bottom;
-
- if (rects[i].width && rects[i].height)
- i++;
-
- rects[i].x = width - input.right;
- rects[i].y = input.top;
- rects[i].width = input.right;
- rects[i].height = height - input.top - input.bottom;
-
- if (rects[i].width && rects[i].height)
- i++;
-
- rects[i].x = 0;
- rects[i].y = height - input.bottom;
- rects[i].width = width;
- rects[i].height = input.bottom;
-
- if (rects[i].width && rects[i].height)
- i++;
-
- XShapeCombineRectangles (d->dpy (),
- frame,
- ShapeInput,
- 0,
- 0,
- rects,
- i,
- ShapeSet,
- YXBanded);
+ XShapeCombineRegion (d->dpy (), frame, ShapeInput,
+ -x, -y, frameRegion, ShapeSet);
}
else
{
@@ -772,39 +731,14 @@ PrivateWindow::updateFrameWindow ()
XDeleteProperty (d->dpy (), id, d->atoms ().frameWindow);
XDestroyWindow (d->dpy (), frame);
frame = None;
+ XSubtractRegion (&emptyRegion, &emptyRegion, frameRegion);
}
}
window->recalcActions ();
}
-void
-CompWindow::setWindowFrameExtents (CompWindowExtents *input)
-{
- if (input->left != priv->input.left ||
- input->right != priv->input.right ||
- input->top != priv->input.top ||
- input->bottom != priv->input.bottom)
- {
- unsigned long data[4];
-
- priv->input = *input;
- data[0] = input->left;
- data[1] = input->right;
- data[2] = input->top;
- data[3] = input->bottom;
-
- updateSize ();
- priv->updateFrameWindow ();
- recalcActions ();
-
- XChangeProperty (priv->screen->display ()->dpy (), priv->id,
- priv->screen->display ()->atoms ().frameExtents,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) data, 4);
- }
-}
void
CompWindow::updateWindowOutputExtents ()
@@ -1383,7 +1317,7 @@ CompWindow::resize (CompWindow::Geometry gm)
priv->invisible = WINDOW_INVISIBLE (priv);
- priv->updateFrameWindow ();
+ updateFrameRegion ();
}
else if (priv->attrib.x != gm.x () || priv->attrib.y != gm.y ())
{
@@ -3923,6 +3857,10 @@ void
WindowInterface::stateChangeNotify (unsigned int lastState)
WRAPABLE_DEF (stateChangeNotify, lastState)
+void
+WindowInterface::updateFrameRegion (Region region)
+ WRAPABLE_DEF (updateFrameRegion, region)
+
Window
CompWindow::id ()
{
@@ -4140,6 +4078,12 @@ CompWindow::region ()
return priv->region;
}
+Region
+CompWindow::frameRegion ()
+{
+ return priv->frameRegion;
+}
+
bool
CompWindow::inShowDesktopMode ()
{
@@ -4433,6 +4377,8 @@ CompWindow::CompWindow (CompScreen *screen,
priv->region = XCreateRegion ();
assert (priv->region);
+ priv->frameRegion = XCreateRegion ();
+ assert (priv->frameRegion);
@@ -4776,6 +4722,9 @@ PrivateWindow::~PrivateWindow ()
if (region)
XDestroyRegion (region);
+ if (frameRegion)
+ XDestroyRegion (frameRegion);
+
if (struts)
free (struts);
@@ -4832,3 +4781,64 @@ CompWindow::mwmFunc ()
{
return priv->mwmFunc;
}
+
+void
+CompWindow::updateFrameRegion ()
+{
+ REGION r;
+
+ if (priv->input.left || priv->input.right ||
+ priv->input.top || priv->input.bottom)
+ {
+
+ XSubtractRegion (&emptyRegion, &emptyRegion, priv->frameRegion);
+
+ updateFrameRegion (priv->frameRegion);
+
+ r.numRects = 1;
+ r.rects = &r.extents;
+ r.extents = priv->region->extents;
+ XSubtractRegion (priv->frameRegion, &r, priv->frameRegion);
+
+ r.extents.x1 -= priv->input.left;
+ r.extents.x2 += priv->input.right;
+ r.extents.y1 -= priv->input.top;
+ r.extents.y2 += priv->input.bottom;
+
+ XIntersectRegion (priv->frameRegion, &r, priv->frameRegion);
+
+ priv->updateFrameWindow ();
+ }
+}
+
+void
+CompWindow::setWindowFrameExtents (CompWindowExtents *i)
+{
+ if (priv->input.left != i->left ||
+ priv->input.right != i->right ||
+ priv->input.top != i->top ||
+ priv->input.bottom != i->bottom)
+ {
+ unsigned long data[4];
+
+ priv->input = *i;
+
+ updateSize ();
+ updateFrameRegion ();
+ recalcActions ();
+
+ data[0] = i->left;
+ data[1] = i->right;
+ data[2] = i->top;
+ data[3] = i->bottom;
+
+ XChangeProperty (priv->screen->display ()->dpy (), priv->id,
+ priv->screen->display ()->atoms ().frameExtents,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 4);
+ }
+}
+
+void
+CompWindow::updateFrameRegion (Region region)
+ WRAPABLE_HND_FUNC(12, updateFrameRegion, region)