Description: Fix window edge behaviour
Author: https://bugs.launchpad.net/bugs/103306
--- a/metadata/wall.xml.in
+++ b/metadata/wall.xml.in
@@ -280,6 +280,7 @@
<_short>Flip Left</_short>
<_long>Flip left</_long>
<nodelay>true</nodelay>
+ <passive_grab>false</passive_grab>
<default>
<edge name="Left"/>
</default>
@@ -289,6 +290,7 @@
<_short>Flip Right</_short>
<_long>Flip right</_long>
<nodelay>true</nodelay>
+ <passive_grab>false</passive_grab>
<default>
<edge name="Right"/>
</default>
@@ -298,6 +300,7 @@
<_short>Flip Up</_short>
<_long>Flip up</_long>
<nodelay>true</nodelay>
+ <passive_grab>false</passive_grab>
<default>
<edge name="Top"/>
</default>
@@ -307,6 +310,7 @@
<_short>Flip Down</_short>
<_long>Flip down</_long>
<nodelay>true</nodelay>
+ <passive_grab>false</passive_grab>
<default>
<edge name="Bottom"/>
</default>
--- a/src/wall/wall.c
+++ b/src/wall/wall.c
@@ -111,6 +111,8 @@ typedef struct _WallScreen
WindowUngrabNotifyProc windowUngrabNotify;
ActivateWindowProc activateWindow;
+ int grabCount;
+
Bool moving; /* Used to track miniview movement */
Bool showPreview;
@@ -178,6 +180,38 @@ typedef struct _WallWindow
static void
+wallScreenOptionChangeNotify (CompScreen *s, CompOption *opt,
+ WallScreenOptions num)
+{
+ WALL_SCREEN (s);
+
+ if (ws->grabCount == -1 || ws->grabCount > 0)
+ {
+ removeScreenAction (s, wallGetFlipLeftEdge(s->display));
+ removeScreenAction (s, wallGetFlipRightEdge(s->display));
+ removeScreenAction (s, wallGetFlipUpEdge(s->display));
+ removeScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+
+ if (wallGetEdgeflipPointer (s) || wallGetEdgeflipMove (s) ||
+ wallGetEdgeflipDnd (s))
+ {
+ if (!wallGetEdgeflipPointer (s) && !wallGetEdgeflipDnd (s))
+ ws->grabCount = 0;
+ else
+ {
+ ws->grabCount = -1;
+ addScreenAction (s, wallGetFlipLeftEdge(s->display));
+ addScreenAction (s, wallGetFlipRightEdge(s->display));
+ addScreenAction (s, wallGetFlipUpEdge(s->display));
+ addScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+ }
+ else
+ ws->grabCount = -2;
+}
+
+static void
wallClearCairoLayer (cairo_t *cr)
{
cairo_save (cr);
@@ -1903,11 +1937,25 @@ wallWindowGrabNotify (CompWindow *w,
unsigned int state,
unsigned int mask)
{
- WALL_SCREEN (w->screen);
+ CompScreen *s = w->screen;
+ WALL_SCREEN (s);
if (!ws->grabWindow)
ws->grabWindow = w;
+ if (ws->grabCount >= 0)
+ {
+ if (!ws->grabCount)
+ {
+ addScreenAction (s, wallGetFlipLeftEdge(s->display));
+ addScreenAction (s, wallGetFlipRightEdge(s->display));
+ addScreenAction (s, wallGetFlipUpEdge(s->display));
+ addScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+
+ ws->grabCount++;
+ }
+
UNWRAP (ws, w->screen, windowGrabNotify);
(*w->screen->windowGrabNotify) (w, x, y, state, mask);
WRAP (ws, w->screen, windowGrabNotify, wallWindowGrabNotify);
@@ -1916,11 +1964,25 @@ wallWindowGrabNotify (CompWindow *w,
static void
wallWindowUngrabNotify (CompWindow *w)
{
- WALL_SCREEN (w->screen);
+ CompScreen *s = w->screen;
+ WALL_SCREEN (s);
if (w == ws->grabWindow)
ws->grabWindow = NULL;
+ if (ws->grabCount >= 0)
+ {
+ ws->grabCount--;
+
+ if (!ws->grabCount)
+ {
+ removeScreenAction (s, wallGetFlipLeftEdge(s->display));
+ removeScreenAction (s, wallGetFlipRightEdge(s->display));
+ removeScreenAction (s, wallGetFlipUpEdge(s->display));
+ removeScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+ }
+
UNWRAP (ws, w->screen, windowUngrabNotify);
(*w->screen->windowUngrabNotify) (w);
WRAP (ws, w->screen, windowUngrabNotify, wallWindowUngrabNotify);
@@ -2122,6 +2184,8 @@ wallInitScreen (CompPlugin *p,
ws->transform = NoTransformation;
ws->direction = -1;
+ ws->grabCount = 0;
+
memset (&ws->switcherContext, 0, sizeof (WallCairoContext));
memset (&ws->thumbContext, 0, sizeof (WallCairoContext));
memset (&ws->highlightContext, 0, sizeof (WallCairoContext));
@@ -2137,6 +2201,27 @@ wallInitScreen (CompPlugin *p,
WRAP (ws, s, windowUngrabNotify, wallWindowUngrabNotify);
WRAP (ws, s, activateWindow, wallActivateWindow);
+ wallSetEdgeflipPointerNotify (s, wallScreenOptionChangeNotify);
+ wallSetEdgeflipMoveNotify (s, wallScreenOptionChangeNotify);
+ wallSetEdgeflipDndNotify (s, wallScreenOptionChangeNotify);
+
+ if (wallGetEdgeflipPointer (s) || wallGetEdgeflipMove (s) ||
+ wallGetEdgeflipDnd (s))
+ {
+ if (!wallGetEdgeflipPointer (s) && !wallGetEdgeflipDnd (s))
+ ws->grabCount = 0;
+ else
+ {
+ ws->grabCount = -1;
+ addScreenAction (s, wallGetFlipLeftEdge(s->display));
+ addScreenAction (s, wallGetFlipRightEdge(s->display));
+ addScreenAction (s, wallGetFlipUpEdge(s->display));
+ addScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+ }
+ else
+ ws->grabCount = -2;
+
s->base.privates[wd->screenPrivateIndex].ptr = ws;
wallCreateCairoContexts (s, TRUE);
@@ -2170,6 +2255,14 @@ wallFiniScreen (CompPlugin *p,
freeWindowPrivateIndex (s, ws->windowPrivateIndex);
+ if (ws->grabCount > 0 || ws->grabCount == -1)
+ {
+ removeScreenAction (s, wallGetFlipLeftEdge(s->display));
+ removeScreenAction (s, wallGetFlipRightEdge(s->display));
+ removeScreenAction (s, wallGetFlipUpEdge(s->display));
+ removeScreenAction (s, wallGetFlipDownEdge(s->display));
+ }
+
free(ws);
}