static void
getTargetRect (CompWindow *cw,
               GridType	  where)
{
    GRID_SCREEN (cw->screen);

    gs->props = gridProps[where];

    DEBUG_PRINT ((gridOut, "\nPressed KP_%i\n", where));

    /* get current available area */
    getWorkareaForOutput (cw->screen, outputDeviceForWindow(cw), &gs->workarea);
    DEBUG_RECT (workarea);

    /* Convention:
     * xxxSlot include decorations (it's the screen area occupied)
     * xxxRect are undecorated (it's the constrained position
    			of the contents)
     */

    /* slice and dice to get desired slot - including decorations */
    gs->desiredSlot.y = gs->workarea.y + gs->props.gravityDown *
                        (gs->workarea.height / gs->props.numCellsY);
    gs->desiredSlot.height = gs->workarea.height / gs->props.numCellsY;
    gs->desiredSlot.x = gs->workarea.x + gs->props.gravityRight *
                        (gs->workarea.width / gs->props.numCellsX);
    gs->desiredSlot.width = gs->workarea.width / gs->props.numCellsX;
    DEBUG_RECT (desiredSlot);

    /* Adjust for constraints and decorations */
    constrainSize (cw, &gs->desiredSlot, &gs->desiredRect);
    DEBUG_RECT (gs->desiredRect);
}
static void
constrainSize (CompWindow *w,
               XRectangle *slot,
               XRectangle *rect)
{
    XRectangle workarea;
    XRectangle r;
    int        cw, ch;

    getWorkareaForOutput (w->screen, outputDeviceForWindow (w), &workarea);
    slotToRect (w, slot, &r);

    if (constrainNewWindowSize (w, r.width, r.height, &cw, &ch))
    {
        /* constrained size may put window offscreen, adjust for that case */
        int dx = r.x + cw - workarea.width - workarea.x + w->input.right;
        int dy = r.y + ch - workarea.height - workarea.y + w->input.bottom;

        if ( dx > 0 )
            r.x -= dx;
        if ( dy > 0 )
            r.y -= dy;

        r.width = cw;
        r.height = ch;
    }

    *rect = r;
}
Exemple #3
0
static void
wsnamesDrawText (CompScreen *s)
{
	GLfloat   alpha;
	int       ox1, ox2, oy1, oy2;
	float     x, y, border = 10.0f;

	WSNAMES_SCREEN (s);

	getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);

	x = ox1 + ((ox2 - ox1) / 2) - (ws->textData->width / 2);

	const BananaValue *
	option_text_placement = bananaGetOption (bananaIndex,
	                                         "text_placement",
	                                         s->screenNum);

	/* assign y (for the lower corner!) according to the setting */
	switch (option_text_placement->i) {
	case TEXT_PLACEMENT_CENTERED_ON_SCREEN:
		y = oy1 + ((oy2 - oy1) / 2) + (ws->textData->height / 2);
		break;
	case TEXT_PLACEMENT_TOP_OF_SCREEN:
	case TEXT_PLACEMENET_BOTTOM_OF_SCREEN:
		{
		XRectangle workArea;
		getWorkareaForOutput (s, s->currentOutputDev, &workArea);

		if (option_text_placement->i == TEXT_PLACEMENT_TOP_OF_SCREEN)
			y = oy1 + workArea.y + (2 * border) + ws->textData->height;
		else
			y = oy1 + workArea.y + workArea.height - (2 * border);
		}
		break;
	default:
		return;
		break;
	}

	const BananaValue *
	option_fade_time = bananaGetOption (bananaIndex,
	                                    "fade_time",
	                                    s->screenNum);

	if (ws->timer)
		alpha = ws->timer / (option_fade_time->f * 1000.0f);
	else
		alpha = 1.0f;

	textDrawText (s, ws->textData, floor (x), floor (y), alpha);
}
static void
ringDrawWindowTitle (CompScreen *s)
{
    float      x, y;
    int        ox1, ox2, oy1, oy2;

    RING_SCREEN (s);
    RING_DISPLAY (s->display);

    getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);

    x = ox1 + ((ox2 - ox1) / 2) - ((int)rs->textData->width / 2);

    /* assign y (for the lower corner!) according to the setting */
    switch (ringGetTitleTextPlacement (s))
    {
	case TitleTextPlacementCenteredOnScreen:
	    y = oy1 + ((oy2 - oy1) / 2) + ((int)rs->textData->height / 2);
	    break;
	case TitleTextPlacementAboveRing:
	case TitleTextPlacementBelowRing:
	    {
		XRectangle workArea;
		getWorkareaForOutput (s, s->currentOutputDev, &workArea);

	    	if (ringGetTitleTextPlacement (s) ==
		    TitleTextPlacementAboveRing)
    		    y = oy1 + workArea.y + (int)rs->textData->height;
		else
		    y = oy1 + workArea.y + workArea.height;
	    }
	    break;
	default:
	    return;
	    break;
    }

    (rd->textFunc->drawText) (s, rs->textData, floor (x), floor (y), 1.0f);
}
static Bool
scaleaddonPullWindow(CompDisplay * d,
		     CompAction * action,
		     CompActionState state, CompOption * option, int nOption)
{
	CompScreen *s;
	Window xid;

	xid = getIntOptionNamed(option, nOption, "root", 0);

	s = findScreenAtDisplay(d, xid);
	if (s) {
		CompWindow *w;

		SCALE_SCREEN(s);
		ADDON_DISPLAY(d);

		if (!ss->grabIndex)
			return FALSE;

		w = findWindowAtDisplay(d, ad->highlightedWindow);
		if (w) {
			int x, y, vx, vy;

			defaultViewportForWindow(w, &vx, &vy);

			x = w->attrib.x + (s->x - vx) * s->width;
			y = w->attrib.y + (s->y - vy) * s->height;

			if (scaleaddonGetConstrainPullToScreen(s)) {
				XRectangle workArea;
				CompWindowExtents extents;

				getWorkareaForOutput(s,
						     outputDeviceForWindow(w),
						     &workArea);

				extents.left = x - w->input.left;
				extents.right = x + w->width + w->input.right;
				extents.top = y - w->input.top;
				extents.bottom =
				    y + w->height + w->input.bottom;

				if (extents.left < workArea.x)
					x += workArea.x - extents.left;
				else if (extents.right >
					 workArea.x + workArea.width)
					x += workArea.x + workArea.width -
					    extents.right;

				if (extents.top < workArea.y)
					y += workArea.y - extents.top;
				else if (extents.bottom >
					 workArea.y + workArea.height)
					y += workArea.y + workArea.height -
					    extents.bottom;
			}

			if (x != w->attrib.x || y != w->attrib.y) {
				SCALE_WINDOW(w);

				moveWindowToViewportPosition(w, x, y, TRUE);

				/* Select this window when ending scale */
				(*ss->selectWindow) (w);

				/* stop scaled window dissapearing */
				sw->tx -= (s->x - vx) * s->width;
				sw->ty -= (s->y - vy) * s->height;

				if (scaleaddonGetExitAfterPull(s)) {
					int opt;
					CompAction *action2;
					CompOption o[1];

					SCALE_DISPLAY(d);

					opt = SCALE_DISPLAY_OPTION_INITIATE_KEY;
					action2 = &sd->opt[opt].value.action;

					o[0].type = CompOptionTypeInt;
					o[0].name = "root";
					o[0].value.i = s->root;

					if (action2->terminate)
						(*action2->terminate) (d,
								       action,
								       0, o, 1);
				} else {
					/* provide a simple animation */
					addWindowDamage(w);

					sw->tx -=
					    (sw->slot->x2 - sw->slot->x1) / 20;
					sw->ty -=
					    (sw->slot->y2 - sw->slot->y1) / 20;
					sw->scale *= 1.1f;
					sw->adjust = TRUE;

					ss->state = SCALE_STATE_OUT;
					addWindowDamage(w);
				}

				return TRUE;
			}
		}
	}

	return FALSE;
}
Exemple #6
0
static Bool
gridPlaceWindow (Window          xid,
                 GridType        where)
{
	CompWindow *w;

	w  = findWindowAtDisplay (xid);
	if (w)
	{
		XRectangle     workarea;
		XRectangle     desiredSlot;
		XRectangle     desiredRect;
		XRectangle     currentRect;
		GridProps      props = gridProps[where];
		XWindowChanges xwc;

		/* get current available area */
		getWorkareaForOutput (w->screen, outputDeviceForWindow(w), &workarea);

		/* Convention:
		 * xxxSlot include decorations (it's the screen area occupied)
		 * xxxRect are undecorated (it's the constrained position
		                            of the contents)
		 */

		/* slice and dice to get desired slot - including decorations */
		desiredSlot.y =  workarea.y + props.gravityDown *
		                 (workarea.height / props.numCellsY);
		desiredSlot.height = workarea.height / props.numCellsY;
		desiredSlot.x =  workarea.x + props.gravityRight *
		                 (workarea.width / props.numCellsX);
		desiredSlot.width = workarea.width / props.numCellsX;

		/* Adjust for constraints and decorations */
		constrainSize (w, &desiredSlot, &desiredRect);

		/* Get current rect not including decorations */
		currentRect.x = w->serverX;
		currentRect.y = w->serverY;
		currentRect.width  = w->serverWidth;
		currentRect.height = w->serverHeight;

		if (desiredRect.y == currentRect.y &&
		    desiredRect.height == currentRect.height)
		{
			int slotWidth33  = workarea.width / 3;
			int slotWidth66  = workarea.width - slotWidth33;

			if (props.numCellsX == 2) /* keys (1, 4, 7, 3, 6, 9) */
			{
				if (currentRect.width == desiredRect.width &&
				    currentRect.x == desiredRect.x)
				{
					desiredSlot.width = slotWidth66;
					desiredSlot.x = workarea.x +
					        props.gravityRight * slotWidth33;
				}
				else
				{
					/* tricky, have to allow for window constraints when
					 * computing what the 33% and 66% offsets would be
					 */
					XRectangle rect33, rect66, slot33, slot66;

					slot33 = desiredSlot;
					slot33.x = workarea.x + props.gravityRight * slotWidth66;
					slot33.width = slotWidth33;
					constrainSize (w, &slot33, &rect33);

					slot66 = desiredSlot;
					slot66.x = workarea.x + props.gravityRight * slotWidth33;
					slot66.width = slotWidth66;
					constrainSize (w, &slot66, &rect66);

					if (currentRect.width == rect66.width &&
					    currentRect.x == rect66.x)
					{
						desiredSlot.width = slotWidth33;
						desiredSlot.x = workarea.x +
						    props.gravityRight * slotWidth66;
					}
				}
			}
			else /* keys (2, 5, 8) */
			{
				if (currentRect.width == desiredRect.width &&
				    currentRect.x == desiredRect.x)
				{
				    desiredSlot.width = slotWidth33;
				    desiredSlot.x = workarea.x + slotWidth33;
				}
			}
			constrainSize (w, &desiredSlot, &desiredRect);
		}

		xwc.x = desiredRect.x;
		xwc.y = desiredRect.y;
		xwc.width  = desiredRect.width;
		xwc.height = desiredRect.height;

		if (w->mapNum)
			sendSyncRequest (w);

		if (w->state & MAXIMIZE_STATE)
		{
			/* maximized state interferes with us, clear it */
			maximizeWindow (w, 0);
		}

		/* TODO: animate move+resize */
		configureXWindow (w, CWX | CWY | CWWidth | CWHeight, &xwc);
	}

	return TRUE;
}