static void
scaleaddonHandleEvent (CompDisplay *d,
                       XEvent      *event)
{
    ADDON_DISPLAY (d);

    UNWRAP (ad, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (ad, d, handleEvent, scaleaddonHandleEvent);

    switch (event->type)
    {
    case PropertyNotify:
    {
        if (event->xproperty.atom == XA_WM_NAME)
        {
            CompWindow *w;

            w = findWindowAtDisplay (d, event->xproperty.window);
            if (w)
            {
                SCALE_SCREEN (w->screen);
                if (ss->grabIndex)
                {
                    scaleaddonRenderWindowTitle (w);
                    addWindowDamage (w);
                }
            }
        }
    }
    break;
    case MotionNotify:
    {
        CompScreen *s;
        s = findScreenAtDisplay (d, event->xmotion.root);

        if (s)
        {
            SCALE_SCREEN (s);
            if (ss->grabIndex)
            {
                SCALE_DISPLAY (d);

                ad->highlightedWindow = sd->hoveredWindow;
                scaleaddonCheckWindowHighlight (s);
            }
        }
    }
    break;
    default:
        break;
    }
}
Beispiel #2
0
static void
scalefilterInitFilterInfo (CompScreen *s)
{
    FILTER_SCREEN (s);
    SCALE_SCREEN (s);

    ScaleFilterInfo *info = fs->filterInfo;

    memset (info->filterString, 0, sizeof (info->filterString));
    info->filterStringLength = 0;

    info->textPixmap = None;
    info->textWidth  = 0;
    info->textHeight = 0;

    info->timeoutHandle = 0;

    info->outputDevice = s->currentOutputDev;

    initTexture (s, &info->textTexture);

    matchInit (&info->match);
    matchCopy (&info->match, &fs->scaleMatch);

    info->origMatch  = ss->currentMatch;
    ss->currentMatch = &info->match;
}
Beispiel #3
0
static Bool
scaleaddonCloseWindow(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) {
			closeWindow(w, getCurrentTimeFromDisplay(d));
			return TRUE;
		}
	}

	return FALSE;
}
Beispiel #4
0
static Bool
scalefilterSetScaledPaintAttributes (CompWindow        *w,
				     WindowPaintAttrib *attrib)
{
    Bool ret;

    FILTER_SCREEN (w->screen);
    SCALE_SCREEN (w->screen);

    UNWRAP (fs, ss, setScaledPaintAttributes);
    ret = (*ss->setScaledPaintAttributes) (w, attrib);
    WRAP (fs, ss, setScaledPaintAttributes, 
	  scalefilterSetScaledPaintAttributes);

    if (fs->matchApplied ||
	(fs->filterInfo && fs->filterInfo->filterStringLength))
    {
	SCALE_WINDOW (w);

	if (ret && !sw->slot)
	{
	    ret = FALSE;
    	    attrib->opacity = 0;
	}
    }

    return ret;
}
Beispiel #5
0
static Bool
scalefilterInitScreen (CompPlugin *p,
	    	       CompScreen *s)
{
    ScaleFilterScreen *fs;

    FILTER_DISPLAY (s->display);
    SCALE_SCREEN (s);

    fs = malloc (sizeof (ScaleFilterScreen));
    if (!fs)
	return FALSE;

    fs->filterInfo = NULL;
    matchInit (&fs->scaleMatch);
    fs->matchApplied = FALSE;

    WRAP (fs, s, paintOutput, scalefilterPaintOutput);
    WRAP (fs, ss, setScaledPaintAttributes,
	  scalefilterSetScaledPaintAttributes);

    scalefilterSetFontBoldNotify (s, scalefilterScreenOptionChanged);
    scalefilterSetFontSizeNotify (s, scalefilterScreenOptionChanged);
    scalefilterSetFontColorNotify (s, scalefilterScreenOptionChanged);
    scalefilterSetBackColorNotify (s, scalefilterScreenOptionChanged);

    s->privates[fd->screenPrivateIndex].ptr = fs;

    return TRUE;
}
Beispiel #6
0
static void
scaleaddonScalePaintDecoration(CompWindow * w,
			       const WindowPaintAttrib * attrib,
			       const CompTransform * transform,
			       Region region, unsigned int mask)
{
	CompScreen *s = w->screen;

	ADDON_SCREEN(s);
	SCALE_SCREEN(s);
	ADDON_WINDOW(w);

	UNWRAP(as, ss, scalePaintDecoration);
	(*ss->scalePaintDecoration) (w, attrib, transform, region, mask);
	WRAP(as, ss, scalePaintDecoration, scaleaddonScalePaintDecoration);

	if ((ss->state == SCALE_STATE_WAIT) || (ss->state == SCALE_STATE_OUT)) {
		if (scaleaddonGetWindowHighlight(s)) {
			ADDON_DISPLAY(s->display);

			if (w->id == ad->highlightedWindow)
				scaleaddonDrawWindowHighlight(w);
		}

		if (aw->textData)
			scaleaddonDrawWindowTitle(w);
	}
}
Beispiel #7
0
static void
scalefilterHandleEvent (CompDisplay *d,
	 		XEvent      *event)
{
    FILTER_DISPLAY (d);

    switch (event->type)
    {
    case KeyPress:
    	{
	    CompScreen *s;
	    s = findScreenAtDisplay (d, event->xkey.root);
	    if (s)
	    {
	        SCALE_SCREEN (s);
		if (ss->grabIndex)
		{
		    XKeyEvent *keyEvent = (XKeyEvent *) event;
		    scalefilterHandleKeyPress (s, keyEvent);
		}
	    }
	}
	break;
    default:
	break;
    }

    UNWRAP (fd, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (fd, d, handleEvent, scalefilterHandleEvent);
}
Beispiel #8
0
static void scaleaddonDonePaintScreen(CompScreen * s)
{
	ADDON_SCREEN(s);
	SCALE_SCREEN(s);

	if (ss->state != SCALE_STATE_NONE && as->lastState == SCALE_STATE_NONE) {
		CompWindow *w;

		for (w = s->windows; w; w = w->next)
			scaleaddonRenderWindowTitle(w);
	} else if (ss->state == SCALE_STATE_NONE &&
		   as->lastState != SCALE_STATE_NONE) {
		CompWindow *w;

		for (w = s->windows; w; w = w->next)
			scaleaddonFreeWindowTitle(w);
	}

	if (ss->state == SCALE_STATE_OUT && as->lastState != SCALE_STATE_OUT) {
		ADDON_DISPLAY(s->display);

		ad->lastHighlightedWindow = None;
		scaleaddonCheckWindowHighlight(s);
	}

	as->lastState = ss->state;

	UNWRAP(as, s, donePaintScreen);
	(*s->donePaintScreen) (s);
	WRAP(as, s, donePaintScreen, scaleaddonDonePaintScreen);
}
static Bool
scaleSetScreenOption (CompPlugin      *plugin,
		      CompScreen      *screen,
		      const char      *name,
		      CompOptionValue *value)
{
    CompOption *o;
    int	       index;

    SCALE_SCREEN (screen);

    o = compFindOption (ss->opt, NUM_OPTIONS (ss), name, &index);

    if (!o)
	return FALSE;

    switch (index) {
    case SCALE_SCREEN_OPTION_OPACITY:
	if (compSetIntOption (o, value))
	{
	    ss->opacity = (OPAQUE * o->value.i) / 100;
	    return TRUE;
	}
	break;
    default:
	return compSetScreenOption (screen, o, value);
    }

    return FALSE;
}
static void
scaleaddonRenderWindowTitle (CompWindow *w)
{
    CompTextAttrib            attrib;
    float                     scale;
    CompScreen                *s = w->screen;
    ScaleaddonWindowTitleEnum winTitleMode;

    ADDON_DISPLAY (s->display);
    SCALE_SCREEN (s);
    SCALE_WINDOW (w);
    ADDON_WINDOW (w);

    scaleaddonFreeWindowTitle (w);

    if (!ad->textFunc)
        return;

    if (!sw->slot)
        return;

    winTitleMode = scaleaddonGetWindowTitle (s);
    if (winTitleMode == WindowTitleNoDisplay)
        return;

    if (winTitleMode == WindowTitleHighlightedWindowOnly &&
            ad->highlightedWindow != w->id)
    {
        return;
    }

    scale = sw->slot->scale;
    attrib.maxWidth = w->attrib.width * scale;
    attrib.maxHeight = w->attrib.height * scale;

    attrib.family = "Sans";
    attrib.size = scaleaddonGetTitleSize (s);
    attrib.color[0] = scaleaddonGetFontColorRed (s);
    attrib.color[1] = scaleaddonGetFontColorGreen (s);
    attrib.color[2] = scaleaddonGetFontColorBlue (s);
    attrib.color[3] = scaleaddonGetFontColorAlpha (s);

    attrib.flags = CompTextFlagWithBackground | CompTextFlagEllipsized;
    if (scaleaddonGetTitleBold (s))
        attrib.flags |= CompTextFlagStyleBold;

    attrib.bgHMargin = scaleaddonGetBorderSize (s);
    attrib.bgVMargin = scaleaddonGetBorderSize (s);
    attrib.bgColor[0] = scaleaddonGetBackColorRed (s);
    attrib.bgColor[1] = scaleaddonGetBackColorGreen (s);
    attrib.bgColor[2] = scaleaddonGetBackColorBlue (s);
    attrib.bgColor[3] = scaleaddonGetBackColorAlpha (s);

    aw->textData = (ad->textFunc->renderWindowTitle) (s, w->id,
                   ss->type == ScaleTypeAll,
                   &attrib);
}
static CompOption *
scaleGetScreenOptions (CompPlugin *plugin,
		       CompScreen *screen,
		       int	  *count)
{
    SCALE_SCREEN (screen);

    *count = NUM_OPTIONS (ss);
    return ss->opt;
}
Beispiel #12
0
static void scaleaddonFiniScreen(CompPlugin * p, CompScreen * s)
{
	ADDON_SCREEN(s);
	SCALE_SCREEN(s);

	UNWRAP(as, s, donePaintScreen);
	UNWRAP(as, ss, scalePaintDecoration);
	UNWRAP(as, ss, selectWindow);
	UNWRAP(as, ss, layoutSlotsAndAssignWindows);

	freeWindowPrivateIndex(s, as->windowPrivateIndex);
	free(as);
}
Beispiel #13
0
static void scaleaddonSelectWindow(CompWindow * w)
{
	CompScreen *s = w->screen;

	ADDON_DISPLAY(s->display);
	ADDON_SCREEN(s);
	SCALE_SCREEN(s);

	ad->highlightedWindow = w->id;

	scaleaddonCheckWindowHighlight(s);

	UNWRAP(as, ss, selectWindow);
	(*ss->selectWindow) (w);
	WRAP(as, ss, selectWindow, scaleaddonSelectWindow);
}
Beispiel #14
0
static void
scalefilterHandleEcompEvent (CompDisplay *d,
	 		      char        *pluginName,
	 		      char        *eventName,
	 		      CompOption  *option,
	 		      int         nOption)
{
    FILTER_DISPLAY (d);

    UNWRAP (fd, d, handleEcompEvent);
    (*d->handleEcompEvent) (d, pluginName, eventName, option, nOption);
    WRAP (fd, d, handleEcompEvent, scalefilterHandleEcompEvent);

    if ((strcmp (pluginName, "scale") == 0) &&
	(strcmp (eventName, "activate") == 0))
    {
	Window xid = getIntOptionNamed (option, nOption, "root", 0);
	Bool activated = getBoolOptionNamed (option, nOption, "active", FALSE);
	CompScreen *s = findScreenAtDisplay (d, xid);

	if (s)
	{
	    FILTER_SCREEN (s);
	    SCALE_SCREEN (s);

	    if (activated)
	    {
		matchFini (&fs->scaleMatch);
		matchInit (&fs->scaleMatch);
		matchCopy (&fs->scaleMatch, ss->currentMatch);
		matchUpdate (d, &fs->scaleMatch);
		fs->matchApplied = FALSE;
	    }

	    if (!activated)
	    {
		if (fs->filterInfo)
		{
		    ss->currentMatch = fs->filterInfo->origMatch;
		    scalefilterFiniFilterInfo (s, TRUE);
		}
		fs->matchApplied = FALSE;
	    }
	}
    }
}
Beispiel #15
0
static Bool
scalefilterFilterTimeout (void *closure)
{
    CompScreen *s = (CompScreen *) closure;

    FILTER_SCREEN (s);
    SCALE_SCREEN (s);

    if (fs->filterInfo)
    {
	ss->currentMatch = fs->filterInfo->origMatch;
	scalefilterFiniFilterInfo (s, FALSE);
	scalefilterRelayout (s);
    }

    return FALSE;
}
Beispiel #16
0
static void
scalefilterFiniScreen (CompPlugin *p,
	    	       CompScreen *s)
{
    FILTER_SCREEN (s);
    SCALE_SCREEN (s);

    UNWRAP (fs, s, paintOutput);
    UNWRAP (fs, ss, setScaledPaintAttributes);

    if (fs->filterInfo)
    {
	ss->currentMatch = fs->filterInfo->origMatch;
	scalefilterFiniFilterInfo (s, TRUE);
    }

    free (fs);
}
Beispiel #17
0
static double
layoutOrganicCalculateOverlap(CompScreen * s, int win, int x, int y)
{
	int i;
	int x1, y1, x2, y2;
	int overlapX, overlapY;
	int xMin, xMax, yMin, yMax;
	double result = -0.01;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	x1 = x;
	y1 = y;
	x2 = x1 + WIN_W(ss->windows[win]) * as->scale;
	y2 = y1 + WIN_H(ss->windows[win]) * as->scale;

	for (i = 0; i < ss->nWindows; i++) {
		if (i == win)
			continue;

		overlapX = overlapY = 0;
		xMax = MAX(ss->slots[i].x1, x1);
		xMin =
		    MIN(ss->slots[i].x1 + WIN_W(ss->windows[i]) * as->scale,
			x2);
		if (xMax <= xMin)
			overlapX = xMin - xMax;

		yMax = MAX(ss->slots[i].y1, y1);
		yMin =
		    MIN(ss->slots[i].y1 + WIN_H(ss->windows[i]) * as->scale,
			y2);

		if (yMax <= yMin)
			overlapY = yMin - yMax;

		result += (double)overlapX *overlapY;
	}

	return result;
}
static Bool
setScaledPaintAttributes (CompWindow        *w,
			  WindowPaintAttrib *attrib)
{
    Bool drawScaled = FALSE;

    SCALE_SCREEN (w->screen);
    SCALE_WINDOW (w);

    if (sw->adjust || sw->slot)
    {
	SCALE_DISPLAY (w->screen->display);

	if (w->id	    != sd->selectedWindow &&
	    ss->opacity != OPAQUE		  &&
	    ss->state   != SCALE_STATE_IN)
	{
	    /* modify opacity of windows that are not active */
	    attrib->opacity = (attrib->opacity * ss->opacity) >> 16;
	}
static Bool
isScaleWin (CompWindow *w)
{
    SCALE_SCREEN (w->screen);

    if (isNeverScaleWin (w))
	return FALSE;

    if (!ss->type || ss->type == ScaleTypeOutput)
    {
	if (!(*w->screen->focusWindow) (w))
	    return FALSE;
    }

    if (w->state & CompWindowStateSkipPagerMask)
	return FALSE;

    if (w->state & CompWindowStateShadedMask)
	return FALSE;

    if (!w->mapNum || w->attrib.map_state != IsViewable)
	return FALSE;

    switch (ss->type) {
    case ScaleTypeGroup:
	if (ss->clientLeader != w->clientLeader &&
	    ss->clientLeader != w->id)
	    return FALSE;
	break;
    case ScaleTypeOutput:
	if (outputDeviceForWindow(w) != w->screen->currentOutputDev)
	    return FALSE;
    default:
	break;
    }

    if (!matchEval (ss->currentMatch, w))
	return FALSE;

    return TRUE;
}
static void
layoutOrganicRemoveOverlap (CompScreen *s,
                            int        areaWidth,
                            int        areaHeight)
{
    int        i, spacing;
    CompWindow *w;

    SCALE_SCREEN (s);
    ADDON_SCREEN (s);

    spacing = ss->opt[SCALE_SCREEN_OPTION_SPACING].value.i;

    while (layoutOrganicLocalSearch (s, areaWidth, areaHeight))
    {
        for (i = 0; i < ss->nWindows; i++)
        {
            int centerX, centerY;
            int newX, newY, newWidth, newHeight;

            w = ss->windows[i];

            centerX = ss->slots[i].x1 + WIN_W (w) / 2;
            centerY = ss->slots[i].y1 + WIN_H (w) / 2;

            newWidth = (int)((1.0 - ORGANIC_STEP) *
                             (double)WIN_W (w)) - spacing / 2;
            newHeight = (int)((1.0 - ORGANIC_STEP) *
                              (double)WIN_H (w)) - spacing / 2;
            newX = centerX - (newWidth / 2);
            newY = centerY - (newHeight / 2);

            ss->slots[i].x1 = newX;
            ss->slots[i].y1 = newY;
            ss->slots[i].x2 = newX + WIN_W (w);
            ss->slots[i].y2 = newY + WIN_H (w);
        }
        as->scale -= ORGANIC_STEP;
    }
}
static Bool
scaleaddonInitScreen (CompPlugin *p,
                      CompScreen *s)
{
    ScaleAddonScreen *as;

    ADDON_DISPLAY (s->display);
    SCALE_SCREEN (s);

    as = malloc (sizeof (ScaleAddonScreen));
    if (!as)
        return FALSE;

    as->windowPrivateIndex = allocateWindowPrivateIndex (s);
    if (as->windowPrivateIndex < 0)
    {
        free (as);
        return FALSE;
    }

    as->scale = 1.0f;
    as->lastState = SCALE_STATE_NONE;

    WRAP (as, s, donePaintScreen, scaleaddonDonePaintScreen);
    WRAP (as, ss, scalePaintDecoration, scaleaddonScalePaintDecoration);
    WRAP (as, ss, selectWindow, scaleaddonSelectWindow);
    WRAP (as, ss, layoutSlotsAndAssignWindows,
          scaleaddonLayoutSlotsAndAssignWindows);

    scaleaddonSetWindowTitleNotify (s, scaleaddonScreenOptionChanged);
    scaleaddonSetTitleBoldNotify (s, scaleaddonScreenOptionChanged);
    scaleaddonSetTitleSizeNotify (s, scaleaddonScreenOptionChanged);
    scaleaddonSetBorderSizeNotify (s, scaleaddonScreenOptionChanged);
    scaleaddonSetFontColorNotify (s, scaleaddonScreenOptionChanged);
    scaleaddonSetBackColorNotify (s, scaleaddonScreenOptionChanged);

    s->base.privates[ad->screenPrivateIndex].ptr = as;

    return TRUE;
}
Beispiel #22
0
static Bool scaleaddonLayoutSlotsAndAssignWindows(CompScreen * s)
{
	Bool status;

	ADDON_SCREEN(s);
	SCALE_SCREEN(s);

	switch (scaleaddonGetLayoutMode(s)) {
	case LayoutModeOrganicExperimental:
		status = layoutOrganicThumbs(s);
		break;
	case LayoutModeNormal:
	default:
		UNWRAP(as, ss, layoutSlotsAndAssignWindows);
		status = (*ss->layoutSlotsAndAssignWindows) (s);
		WRAP(as, ss, layoutSlotsAndAssignWindows,
		     scaleaddonLayoutSlotsAndAssignWindows);
		break;
	}

	return status;
}
Beispiel #23
0
static Bool layoutOrganicThumbs(CompScreen * s)
{
	CompWindow *w;
	int i, moMode;
	XRectangle workArea;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	moMode = ss->opt[SCALE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i;

	switch (moMode) {
	case SCALE_MOMODE_ALL:
		workArea = s->workArea;
		break;
	case SCALE_MOMODE_CURRENT:
	default:
		workArea = s->outputDev[s->currentOutputDev].workArea;
		break;
	}

	as->scale = 1.0f;

	qsort(ss->windows, ss->nWindows, sizeof(CompWindow *),
	      organicCompareWindows);

	for (i = 0; i < ss->nWindows; i++) {
		w = ss->windows[i];
		SCALE_WINDOW(w);

		sw->slot = &ss->slots[i];
		ss->slots[i].x1 = WIN_X(w) - workArea.x;
		ss->slots[i].y1 = WIN_Y(w) - workArea.y;
		ss->slots[i].x2 = WIN_X(w) + WIN_W(w) - workArea.x;
		ss->slots[i].y2 = WIN_Y(w) + WIN_H(w) - workArea.y;

		if (ss->slots[i].x1 < 0) {
			ss->slots[i].x2 += abs(ss->slots[i].x1);
			ss->slots[i].x1 = 0;
		}
		if (ss->slots[i].x2 > workArea.width - workArea.x) {
			ss->slots[i].x1 -=
			    abs(ss->slots[i].x2 - workArea.width);
			ss->slots[i].x2 = workArea.width - workArea.x;
		}

		if (ss->slots[i].y1 < 0) {
			ss->slots[i].y2 += abs(ss->slots[i].y1);
			ss->slots[i].y1 = 0;
		}
		if (ss->slots[i].y2 > workArea.height - workArea.y) {
			ss->slots[i].y1 -= abs(ss->slots[i].y2 -
					       workArea.height - workArea.y);
			ss->slots[i].y2 = workArea.height - workArea.y;
		}
	}

	ss->nSlots = ss->nWindows;

	layoutOrganicRemoveOverlap(s, workArea.width - workArea.x,
				   workArea.height - workArea.y);
	for (i = 0; i < ss->nWindows; i++) {
		w = ss->windows[i];
		SCALE_WINDOW(w);

		if (ss->type == ScaleTypeGroup)
			raiseWindow(ss->windows[i]);

		ss->slots[i].x1 += w->input.left + workArea.x;
		ss->slots[i].x2 += w->input.left + workArea.x;
		ss->slots[i].y1 += w->input.top + workArea.y;
		ss->slots[i].y2 += w->input.top + workArea.y;
		sw->adjust = TRUE;
	}

	return TRUE;
}
Beispiel #24
0
static Bool
layoutOrganicLocalSearch(CompScreen * s, int areaWidth, int areaHeight)
{
	Bool improvement;
	int i;
	double totalOverlap;

	SCALE_SCREEN(s);

	do {
		improvement = FALSE;
		for (i = 0; i < ss->nWindows; i++) {
			Bool improved;

			do {
				int newX, newY;
				double oldOverlap, overlapH, overlapV;

				improved = FALSE;
				oldOverlap = layoutOrganicCalculateOverlap(s, i,
									   ss->
									   slots
									   [i].
									   x1,
									   ss->
									   slots
									   [i].
									   y1);

				overlapH =
				    layoutOrganicFindBestHorizontalPosition(s,
									    i,
									    &newX,
									    areaWidth);
				overlapV =
				    layoutOrganicFindBestVerticalPosition(s, i,
									  &newY,
									  areaHeight);

				if (overlapH < oldOverlap - 0.1 ||
				    overlapV < oldOverlap - 0.1) {
					improved = TRUE;
					improvement = TRUE;
					if (overlapV > overlapH)
						ss->slots[i].x1 = newX;
					else
						ss->slots[i].y1 = newY;
				}
			}
			while (improved);
		}
	}
	while (improvement);

	totalOverlap = 0.0;
	for (i = 0; i < ss->nWindows; i++) {
		totalOverlap += layoutOrganicCalculateOverlap(s, i,
							      ss->slots[i].x1,
							      ss->slots[i].y1);
	}

	return (totalOverlap > 0.1);
}
Beispiel #25
0
static double
layoutOrganicFindBestVerticalPosition(CompScreen * s,
				      int win, int *bestY, int areaHeight)
{
	int i, x1, x2, h;
	double bestOverlap = 1e31, overlap;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	x1 = ss->slots[win].x1;
	x2 = ss->slots[win].x1 + WIN_W(ss->windows[win]) * as->scale;
	h = WIN_H(ss->windows[win]) * as->scale;
	*bestY = ss->slots[win].y1;

	for (i = 0; i < ss->nWindows; i++) {
		CompWindow *w = ss->windows[i];

		if (i == win)
			continue;

		if (ss->slots[i].x1 < x2 &&
		    ss->slots[i].x1 + WIN_W(w) * as->scale > x1) {
			if (ss->slots[i].y1 - h >= 0
			    && ss->slots[i].y1 < areaHeight) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win, x1,
								  ss->slots[i].
								  y1 - h);
				if (overlap < bestOverlap) {
					*bestY = ss->slots[i].y1 - h;
					bestOverlap = overlap;
				}
			}
			if (WIN_H(w) * as->scale + ss->slots[i].y1 > 0 &&
			    WIN_H(w) * as->scale + h + ss->slots[i].y1 <
			    areaHeight) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win, x1,
								  WIN_H(w) *
								  as->scale +
								  ss->slots[i].
								  y1);

				if (overlap < bestOverlap) {
					*bestY =
					    ss->slots[i].y1 +
					    WIN_H(w) * as->scale;
					bestOverlap = overlap;
				}
			}
		}
	}

	overlap = layoutOrganicCalculateOverlap(s, win, x1, 0);
	if (overlap < bestOverlap) {
		*bestY = 0;
		bestOverlap = overlap;
	}

	overlap = layoutOrganicCalculateOverlap(s, win, x1, areaHeight - h);
	if (overlap < bestOverlap) {
		*bestY = areaHeight - h;
		bestOverlap = overlap;
	}

	return bestOverlap;
}
Beispiel #26
0
static double
layoutOrganicFindBestHorizontalPosition(CompScreen * s,
					int win, int *bestX, int areaWidth)
{
	int i, y1, y2, w;
	double bestOverlap = 1e31, overlap;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	y1 = ss->slots[win].y1;
	y2 = ss->slots[win].y1 + WIN_H(ss->windows[win]) * as->scale;

	w = WIN_W(ss->windows[win]) * as->scale;
	*bestX = ss->slots[win].x1;

	for (i = 0; i < ss->nWindows; i++) {
		CompWindow *lw = ss->windows[i];
		if (i == win)
			continue;

		if (ss->slots[i].y1 < y2 &&
		    ss->slots[i].y1 + WIN_H(lw) * as->scale > y1) {
			if (ss->slots[i].x1 - w >= 0) {
				overlap = layoutOrganicCalculateOverlap(s, win,
									ss->
									slots
									[i].x1 -
									w, y1);

				if (overlap < bestOverlap) {
					*bestX = ss->slots[i].x1 - w;
					bestOverlap = overlap;
				}
			}
			if (WIN_W(lw) * as->scale + ss->slots[i].x1 + w <
			    areaWidth) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win,
								  ss->slots[i].
								  x1 +
								  WIN_W(lw) *
								  as->scale,
								  y1);

				if (overlap < bestOverlap) {
					*bestX =
					    ss->slots[i].x1 +
					    WIN_W(lw) * as->scale;
					bestOverlap = overlap;
				}
			}
		}
	}

	overlap = layoutOrganicCalculateOverlap(s, win, 0, y1);
	if (overlap < bestOverlap) {
		*bestX = 0;
		bestOverlap = overlap;
	}

	overlap = layoutOrganicCalculateOverlap(s, win, areaWidth - w, y1);
	if (overlap < bestOverlap) {
		*bestX = areaWidth - w;
		bestOverlap = overlap;
	}

	return bestOverlap;
}
Beispiel #27
0
static void
scalefilterHandleKeyPress (CompScreen *s,
			   XKeyEvent  *event)
{
    ScaleFilterInfo *info;
    Bool            needRelayout = FALSE;
    Bool            dropKeyEvent = FALSE;
    int             count, timeout;
    char            buffer[10];
    wchar_t         wbuffer[10];
    KeySym          ks;

    FILTER_DISPLAY (s->display);
    FILTER_SCREEN (s);
    SCALE_SCREEN (s);

    info = fs->filterInfo;
    memset (buffer, 0, sizeof (buffer));
    memset (wbuffer, 0, sizeof (wbuffer));

    if (fd->xic)
    {
	Status status;

	XSetICFocus (fd->xic);
	count = Xutf8LookupString (fd->xic, event, buffer, 9, &ks, &status);
	XUnsetICFocus (fd->xic);
    }
    else
    {
	count = XLookupString (event, buffer, 9, &ks, NULL);
    }

    mbstowcs (wbuffer, buffer, 9);

    if (ks == XK_Escape)
    {
	if (info)
	{
	    /* Escape key - drop current filter */
	    ss->currentMatch = info->origMatch;
	    scalefilterFiniFilterInfo (s, TRUE);
	    needRelayout = TRUE;
	    dropKeyEvent = TRUE;
	}
	else if (fs->matchApplied)
	{
	    /* remove filter applied previously
	       if currently not in input mode */
	    matchFini (&ss->match);
	    matchInit (&ss->match);
	    matchCopy (&ss->match, &fs->scaleMatch);
	    matchUpdate (s->display, &ss->match);

	    ss->currentMatch = &ss->match;
	    fs->matchApplied = FALSE;
	    needRelayout = TRUE;
	    dropKeyEvent = TRUE;
	}
    }
    else if (ks == XK_Return)
    {
	if (info)
	{
	    /* Return key - apply current filter persistently */
	    matchFini (&ss->match);
	    matchInit (&ss->match);
	    matchCopy (&ss->match, &info->match);
	    matchUpdate (s->display, &ss->match);

	    ss->currentMatch = &ss->match;
	    fs->matchApplied = TRUE;
	    dropKeyEvent = TRUE;
	    needRelayout = TRUE;
	    scalefilterFiniFilterInfo (s, TRUE);
	}
    }
    else if (ks == XK_BackSpace)
    {
	if (info && info->filterStringLength > 0)
	{
	    /* remove last character in string */
	    info->filterString[--(info->filterStringLength)] = '\0';
	    needRelayout = TRUE;
	}
    }
    else if (count > 0)
    {
	if (!info)
	{
	    fs->filterInfo = info = malloc (sizeof (ScaleFilterInfo));
	    scalefilterInitFilterInfo (s);
	}
	else if (info->timeoutHandle)
	    compRemoveTimeout (info->timeoutHandle);

	timeout = scalefilterGetTimeout (s);
	if (timeout > 0)
	    info->timeoutHandle = compAddTimeout (timeout,
				     		  scalefilterFilterTimeout, s);

	if (info->filterStringLength < MAX_FILTER_SIZE)
	{
	    info->filterString[info->filterStringLength++] = wbuffer[0];
	    info->filterString[info->filterStringLength] = '\0';
	    needRelayout = TRUE;
	}
    }

    /* set the event type invalid if we
       don't want other plugins see it */
    if (dropKeyEvent)
	event->type = LASTEvent+1;

    if (needRelayout)
    {
	scalefilterRenderFilterText (s);

	if (fs->filterInfo)
	    scalefilterUpdateFilter (s, &fs->filterInfo->match);

	scalefilterRelayout (s);
    }
}
static void
scalePaintDecoration (CompWindow	      *w,
		      const WindowPaintAttrib *attrib,
		      const CompTransform     *transform,
		      Region		      region,
		      unsigned int	      mask)
{
    CompScreen *s = w->screen;

    SCALE_SCREEN (s);

    if (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i != SCALE_ICON_NONE)
    {
	WindowPaintAttrib sAttrib = *attrib;
	CompIcon	  *icon;

	SCALE_WINDOW (w);

	icon = getWindowIcon (w, 96, 96);
	if (!icon)
	    icon = w->screen->defaultIcon;

	if (icon && (icon->texture.name || iconToTexture (w->screen, icon)))
	{
	    REGION iconReg;
	    float  scale;
	    float  x, y;
	    int    width, height;
	    int    scaledWinWidth, scaledWinHeight;
	    float  ds;

	    scaledWinWidth  = w->width  * sw->scale;
	    scaledWinHeight = w->height * sw->scale;

	    switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) {
	    case SCALE_ICON_NONE:
	    case SCALE_ICON_EMBLEM:
		scale = 1.0f;
		break;
	    case SCALE_ICON_BIG:
	    default:
		sAttrib.opacity /= 3;
		scale = MIN (((float) scaledWinWidth / icon->width),
			     ((float) scaledWinHeight / icon->height));
		break;
	    }

	    width  = icon->width  * scale;
	    height = icon->height * scale;

	    switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) {
	    case SCALE_ICON_NONE:
	    case SCALE_ICON_EMBLEM:
		x = w->attrib.x + scaledWinWidth - icon->width;
		y = w->attrib.y + scaledWinHeight - icon->height;
		break;
	    case SCALE_ICON_BIG:
	    default:
		x = w->attrib.x + scaledWinWidth / 2 - width / 2;
		y = w->attrib.y + scaledWinHeight / 2 - height / 2;
		break;
	    }

	    x += sw->tx;
	    y += sw->ty;

	    if (sw->slot)
	    {
		sw->delta =
		    fabs (sw->slot->x1 - w->attrib.x) +
		    fabs (sw->slot->y1 - w->attrib.y) +
		    fabs (1.0f - sw->slot->scale) * 500.0f;
	    }

	    if (sw->delta)
	    {
		float o;

		ds =
		    fabs (sw->tx) +
		    fabs (sw->ty) +
		    fabs (1.0f - sw->scale) * 500.0f;

		if (ds > sw->delta)
		    ds = sw->delta;

		o = ds / sw->delta;

		if (sw->slot)
		{
		    if (o < sw->lastThumbOpacity)
			o = sw->lastThumbOpacity;
		}
		else
		{
		    if (o > sw->lastThumbOpacity)
			o = 0.0f;
		}

		sw->lastThumbOpacity = o;

		sAttrib.opacity = sAttrib.opacity * o;
	    }

	    mask |= PAINT_WINDOW_BLEND_MASK;

	    iconReg.rects    = &iconReg.extents;
	    iconReg.numRects = 1;

	    iconReg.extents.x1 = 0;
	    iconReg.extents.y1 = 0;
	    iconReg.extents.x2 = iconReg.extents.x1 + width;
	    iconReg.extents.y2 = iconReg.extents.y1 + height;

	    w->vCount = w->indexCount = 0;
	    if (iconReg.extents.x1 < iconReg.extents.x2 &&
		iconReg.extents.y1 < iconReg.extents.y2)
		(*w->screen->addWindowGeometry) (w,
						 &icon->texture.matrix, 1,
						 &iconReg, &iconReg);

	    if (w->vCount)
	    {
		FragmentAttrib fragment;
		CompTransform  wTransform = *transform;

		initFragmentAttrib (&fragment, &sAttrib);

		matrixScale (&wTransform, scale, scale, 1.0f);
		matrixTranslate (&wTransform, x / scale, y / scale, 0.0f);

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);

		(*w->screen->drawWindowTexture) (w,
						 &icon->texture, &fragment,
						 mask);

		glPopMatrix ();
	    }
	}
    }
}
Beispiel #29
0
static Bool
scaleaddonZoomWindow(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) {
			SCALE_WINDOW(w);
			ADDON_WINDOW(w);

			XRectangle outputRect;
			BOX outputBox;
			int head;

			if (!sw->slot)
				return FALSE;

			head =
			    outputDeviceForPoint(s, sw->slot->x1, sw->slot->y1);
			outputBox = w->screen->outputDev[head].region.extents;

			outputRect.x = outputBox.x1;
			outputRect.y = outputBox.y1;
			outputRect.width = outputBox.x2 - outputBox.x1;
			outputRect.height = outputBox.y2 - outputBox.y1;

			/* damage old rect */
			addWindowDamage(w);

			if (!aw->rescaled) {
				aw->oldAbove = w->next;
				raiseWindow(w);

				/* backup old values */
				aw->origSlot = *sw->slot;

				aw->rescaled = TRUE;

				sw->slot->x1 =
				    (outputRect.width / 2) - (WIN_W(w) / 2) +
				    w->input.left + outputRect.x;
				sw->slot->y1 =
				    (outputRect.height / 2) - (WIN_H(w) / 2) +
				    w->input.top + outputRect.y;
				sw->slot->x2 = sw->slot->x1 + WIN_W(w);
				sw->slot->y2 = sw->slot->y1 + WIN_H(w);
				sw->slot->scale = 1.0f;
			} else {
				if (aw->oldAbove)
					restackWindowBelow(w, aw->oldAbove);

				aw->rescaled = FALSE;
				*(sw->slot) = aw->origSlot;
			}

			sw->adjust = TRUE;
			ss->state = SCALE_STATE_OUT;

			/* slot size may have changed, so
			 * update window title */
			scaleaddonRenderWindowTitle(w);

			addWindowDamage(w);

			return TRUE;
		}
	}

	return FALSE;
}
Beispiel #30
0
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;
}