summaryrefslogtreecommitdiff
path: root/beryl-plugins/src/move.c
diff options
context:
space:
mode:
authormaniac <maniac@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-12-29 14:01:39 +0000
committermaniac <maniac@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-12-29 14:01:39 +0000
commit455ea8f15635e78c5b7d57095fbeab08a2755f87 (patch)
tree92d6ebd766062c793f087f697b035102cba8e914 /beryl-plugins/src/move.c
parent2bd5379ba8954cdc81afcce6f9e1b6f10f0c3ef5 (diff)
downloadmarex-dev-455ea8f15635e78c5b7d57095fbeab08a2755f87.tar.gz
marex-dev-455ea8f15635e78c5b7d57095fbeab08a2755f87.tar.bz2
beryl-plugins (move):
- fix movement constraints for multihead (David Reveman) - unify constrain to top/bottom options git-svn-id: file:///beryl/trunk@2154 d7aaf104-2d23-0410-ae22-9d23157bf5a3
Diffstat (limited to 'beryl-plugins/src/move.c')
-rw-r--r--beryl-plugins/src/move.c177
1 files changed, 132 insertions, 45 deletions
diff --git a/beryl-plugins/src/move.c b/beryl-plugins/src/move.c
index 0ea547f..4af97c3 100644
--- a/beryl-plugins/src/move.c
+++ b/beryl-plugins/src/move.c
@@ -41,9 +41,7 @@
#define MOVE_OPACITY_MIN 1
#define MOVE_OPACITY_MAX 100
-#define MOVE_CONSTRAIN_Y_TOP_DEFAULT TRUE
-#define MOVE_CONSTRAIN_Y_BOTTOM_DEFAULT FALSE
-
+#define MOVE_CONSTRAIN_Y_DEFAULT TRUE
#define MOVE_SNAPOFF_MAXIMIZED_DEFAULT TRUE
#define MOVE_OPACIFY_MIN_OPACITY_DEFAULT 80
@@ -81,15 +79,14 @@ struct _MoveKeys
static int displayPrivateIndex;
-#define MOVE_DISPLAY_OPTION_INITIATE 0
-#define MOVE_DISPLAY_OPTION_OPACITY 1
-#define MOVE_DISPLAY_OPTION_CONSTRAIN_Y_TOP 2
-#define MOVE_DISPLAY_OPTION_CONSTRAIN_Y_BOTTOM 3
-#define MOVE_DISPLAY_OPTION_SNAPOFF_MAXIMIZED 4
-#define MOVE_DISPLAY_OPTION_OPACIFY_MIN_OPACITY 5
-#define MOVE_DISPLAY_OPTION_SNAPOFF_DISTANCE 6
-#define MOVE_DISPLAY_OPTION_SNAPBACK_DISTANCE 7
-#define MOVE_DISPLAY_OPTION_NUM 8
+#define MOVE_DISPLAY_OPTION_INITIATE 0
+#define MOVE_DISPLAY_OPTION_OPACITY 1
+#define MOVE_DISPLAY_OPTION_CONSTRAIN_Y 2
+#define MOVE_DISPLAY_OPTION_SNAPOFF_MAXIMIZED 3
+#define MOVE_DISPLAY_OPTION_OPACIFY_MIN_OPACITY 4
+#define MOVE_DISPLAY_OPTION_SNAPOFF_DISTANCE 5
+#define MOVE_DISPLAY_OPTION_SNAPBACK_DISTANCE 6
+#define MOVE_DISPLAY_OPTION_NUM 7
typedef struct _MoveDisplay
{
@@ -101,6 +98,8 @@ typedef struct _MoveDisplay
CompWindow *w;
int x;
int y;
+ Region region;
+ int status;
KeyCode key[NUM_KEYS];
@@ -183,6 +182,14 @@ moveInitiate(CompDisplay * d,
if (state & CompActionStateInitButton)
action->state |= CompActionStateTermButton;
+ if (md->region)
+ {
+ XDestroyRegion (md->region);
+ md->region = NULL;
+ }
+
+ md->status = RectangleOut;
+
md->x = 0;
md->y = 0;
@@ -256,6 +263,58 @@ moveTerminate(CompDisplay * d,
return FALSE;
}
+/* creates a region containing top and bottom struts. only struts that are
+ outside the screen workarea are considered. */
+static Region
+moveGetYConstrainRegion (CompScreen *s)
+{
+ CompWindow *w;
+ Region region;
+ REGION r;
+
+ region = XCreateRegion ();
+ if (!region)
+ return NULL;
+
+ r.rects = &r.extents;
+ r.numRects = r.size = 1;
+
+ r.extents.x1 = MINSHORT;
+ r.extents.y1 = 0;
+ r.extents.x2 = MAXSHORT;
+ r.extents.y2 = s->height;
+
+ XUnionRegion (&r, region, region);
+
+ for (w = s->windows; w; w = w->next)
+ {
+ if (!w->mapNum)
+ continue;
+
+ if (w->struts)
+ {
+ r.extents.x1 = w->struts->top.x;
+ r.extents.y1 = w->struts->top.y;
+ r.extents.x2 = r.extents.x1 + w->struts->top.width;
+ r.extents.y2 = r.extents.y1 + w->struts->top.height;
+
+ if (r.extents.y2 <= s->workArea.y)
+ XSubtractRegion (region, &r, region);
+
+ r.extents.x1 = w->struts->bottom.x;
+ r.extents.y1 = w->struts->bottom.y;
+ r.extents.x2 = r.extents.x1 + w->struts->bottom.width;
+ r.extents.y2 = r.extents.y1 + w->struts->bottom.height;
+
+ if (r.extents.y1 >= (s->workArea.y + s->workArea.height))
+ XSubtractRegion (region, &r, region);
+ }
+ }
+
+ return region;
+}
+
+
static void moveHandleMotionEvent(CompScreen * s, int xRoot, int yRoot)
{
MOVE_SCREEN(s);
@@ -284,26 +343,66 @@ static void moveHandleMotionEvent(CompScreen * s, int xRoot, int yRoot)
}
else
{
+ XRectangle workArea;
int min, max;
dx = md->x;
dy = md->y;
- max = workArea.y + workArea.height;
- min = workArea.y + w->input.top;
+ screenGetOutputDevWorkArea(s, outputDeviceForWindow(w), &workArea);
- if (md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y_TOP].value.b)
- {
- if (w->attrib.y + dy < min)
- dy = min - w->attrib.y;
- if (w->attrib.y + dy > max)
- dy = max - w->attrib.y;
- }
- if (!w->shaded
- && md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y_BOTTOM].value.b)
+ if (!w->shaded && md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y].value.b)
{
- if (w->attrib.y + dy + w->serverHeight > max)
- dy = max - w->attrib.y - w->serverHeight;
+ if (!md->region)
+ md->region = moveGetYConstrainRegion (s);
+
+ /* make sure that the top frame extents or the top row of
+ pixels are within what is currently our valid screen
+ region */
+ if (md->region)
+ {
+ int x, y, width, height;
+ int status;
+
+ x = w->attrib.x + dx - w->input.left;
+ y = w->attrib.y + dy - w->input.top;
+ width = w->width + w->input.left + w->input.right;
+ height = w->input.top ? w->input.top : 1;
+
+ status = XRectInRegion (md->region, x, y, width, height);
+
+ /* only constrain movement if previous position was valid */
+ if (md->status == RectangleIn)
+ {
+ int xStatus = status;
+
+ while (dx && xStatus != RectangleIn)
+ {
+ xStatus = XRectInRegion (md->region,
+ x, y - dy, width, height);
+
+ if (xStatus != RectangleIn)
+ dx += (dx < 0) ? 1 : -1;
+
+ x = w->attrib.x + dx - w->input.left;
+ }
+
+ while (dy && status != RectangleIn)
+ {
+ status = XRectInRegion (md->region,
+ x, y, width, height);
+
+ if (status != RectangleIn)
+ dy += (dy < 0) ? 1 : -1;
+
+ y = w->attrib.y + dy - w->input.top;
+ }
+ }
+ else
+ {
+ md->status = status;
+ }
+ }
}
if (md->opt[MOVE_DISPLAY_OPTION_SNAPOFF_MAXIMIZED].value.b)
@@ -636,29 +735,17 @@ static void moveDisplayInitOptions(MoveDisplay * md)
o->rest.i.min = MOVE_OPACITY_MIN;
o->rest.i.max = MOVE_OPACITY_MAX;
- o = &md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y_TOP];
- o->advanced = False;
- o->name = "constrain_y_top";
- o->group = N_("Misc. options");
- o->subGroup = N_("Movement constraints");
- o->displayHints = "";
- o->shortDesc = N_("Constrain Y to top of screen");
- o->longDesc =
- N_("Prevent windows from moving over the top of the screen");
- o->type = CompOptionTypeBool;
- o->value.b = MOVE_CONSTRAIN_Y_TOP_DEFAULT;
-
- o = &md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y_BOTTOM];
+ o = &md->opt[MOVE_DISPLAY_OPTION_CONSTRAIN_Y];
o->advanced = False;
- o->name = "constrain_y_bottom";
+ o->name = "constrain_y";
o->group = N_("Misc. options");
- o->subGroup = N_("Movement constraints");
+ o->subGroup = N_("");
o->displayHints = "";
- o->shortDesc = N_("Constrain Y to bottom");
+ o->shortDesc = N_("Constrain Y to screen area");
o->longDesc =
- N_("Prevent windows from moving past the bottom of the screen");
+ N_("Prevent windows from moving out of the screen vertically");
o->type = CompOptionTypeBool;
- o->value.b = MOVE_CONSTRAIN_Y_BOTTOM_DEFAULT;
+ o->value.b = MOVE_CONSTRAIN_Y_DEFAULT;
o = &md->opt[MOVE_DISPLAY_OPTION_SNAPOFF_MAXIMIZED];
o->advanced = False;
@@ -757,8 +844,7 @@ moveSetDisplayOption(CompDisplay * display,
if (compSetIntOption(o, value))
return TRUE;
break;
- case MOVE_DISPLAY_OPTION_CONSTRAIN_Y_TOP:
- case MOVE_DISPLAY_OPTION_CONSTRAIN_Y_BOTTOM:
+ case MOVE_DISPLAY_OPTION_CONSTRAIN_Y:
case MOVE_DISPLAY_OPTION_SNAPOFF_MAXIMIZED:
if (compSetBoolOption(o, value))
return TRUE;
@@ -793,6 +879,7 @@ static Bool moveInitDisplay(CompPlugin * p, CompDisplay * d)
moveDisplayInitOptions(md);
md->w = 0;
+ md->region = NULL;
for (i = 0; i < NUM_KEYS; i++)
md->key[i] = XKeysymToKeycode(d->display,