Пример #1
0
static void
groupChangeNotify (const char        *optionName,
                   BananaType        optionType,
                   const BananaValue *optionValue,
                   int               screenNum)
{
    GROUP_DISPLAY (&display);

    if (strcasecmp (optionName, "window_match") == 0)
    {
        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        matchFini (&gs->window_match);
        matchInit (&gs->window_match);
        matchAddFromString (&gs->window_match, optionValue->s);
        matchUpdate (&gs->window_match);
    }
    else if (strcasecmp (optionName, "tab_base_color") == 0 ||
             strcasecmp (optionName, "tab_highlight_color") == 0 ||
             strcasecmp (optionName, "tab_border_color") == 0 ||
             strcasecmp (optionName, "tab_style") == 0 ||
             strcasecmp (optionName, "border_radius") == 0 ||
             strcasecmp (optionName, "border_width") == 0)
    {
        GroupSelection *group;

        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        for (group = gs->groups; group; group = group->next)
            if (group->tabBar)
                groupRenderTabBarBackground (group);
    }
    else if (strcasecmp (optionName, "tabbar_font_size") == 0 ||
             strcasecmp (optionName, "tabbar_font_color") == 0)
    {
        GroupSelection *group;

        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        for (group = gs->groups; group; group = group->next)
            groupRenderWindowTitle (group);
    }
    else if (strcasecmp (optionName, "thumb_size") == 0 ||
             strcasecmp (optionName, "thumb_space") == 0)
    {
        GroupSelection *group;

        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        for (group = gs->groups; group; group = group->next)
            if (group->tabBar)
            {
                BoxPtr box = &group->tabBar->region->extents;
                groupRecalcTabBarPos (group, (box->x1 + box->x2 ) / 2,
                                      box->x1, box->x2);
            }
    }
    else if (strcasecmp (optionName, "glow") == 0 ||
             strcasecmp (optionName, "glow_size") == 0)
    {
        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        CompWindow *w;

        for (w = s->windows; w; w = w->next)
        {
            GROUP_WINDOW (w);

            groupComputeGlowQuads (w, &gs->glowTexture.matrix);
            if (gw->glowQuads)
            {
                damageWindowOutputExtents (w);
                updateWindowOutputExtents (w);
                damageWindowOutputExtents (w);
            }
        }
    }
    else if (strcasecmp (optionName, "glow_type") == 0)
    {
        CompScreen *s = getScreenFromScreenNum (screenNum);
        GROUP_SCREEN (s);

        int glowType;
        GlowTextureProperties *glowProperty;

        GROUP_DISPLAY (&display);

        const BananaValue *
        option_glow_type = bananaGetOption (bananaIndex,
                                            "glow_type",
                                            s->screenNum);

        glowType = option_glow_type->i;
        glowProperty = &gd->glowTextureProperties[glowType];

        finiTexture (s, &gs->glowTexture);
        initTexture (s, &gs->glowTexture);

        imageDataToTexture (s, &gs->glowTexture,
                            glowProperty->textureData,
                            glowProperty->textureSize,
                            glowProperty->textureSize,
                            GL_RGBA, GL_UNSIGNED_BYTE);

        const BananaValue *
        option_glow = bananaGetOption (bananaIndex,
                                       "glow",
                                       s->screenNum);

        if (option_glow->b && gs->groups)
        {
            CompWindow *w;

            for (w = s->windows; w; w = w->next)
                groupComputeGlowQuads (w, &gs->glowTexture.matrix);

            damageScreen (s);
        }
    }
    else if (strcasecmp (optionName, "select_button") == 0)
        updateButton (optionValue->s, &gd->select_button);
    else if (strcasecmp (optionName, "select_single_key") == 0)
        updateKey (optionValue->s, &gd->select_single_key);
    else if (strcasecmp (optionName, "group_key") == 0)
        updateKey (optionValue->s, &gd->group_key);
    else if (strcasecmp (optionName, "ungroup_key") == 0)
        updateKey (optionValue->s, &gd->ungroup_key);
    else if (strcasecmp (optionName, "remove_key") == 0)
        updateKey (optionValue->s, &gd->remove_key);
    else if (strcasecmp (optionName, "close_key") == 0)
        updateKey (optionValue->s, &gd->close_key);
    else if (strcasecmp (optionName, "ignore_key") == 0)
        updateKey (optionValue->s, &gd->ignore_key);
    else if (strcasecmp (optionName, "tabmode_key") == 0)
        updateKey (optionValue->s, &gd->tabmode_key);
    else if (strcasecmp (optionName, "change_tab_left_key") == 0)
        updateKey (optionValue->s, &gd->change_tab_left_key);
    else if (strcasecmp (optionName, "change_tab_right_key") == 0)
        updateKey (optionValue->s, &gd->change_tab_right_key);
    else if (strcasecmp (optionName, "change_color_key") == 0)
        updateKey (optionValue->s, &gd->change_color_key);
    else if (strcasecmp (optionName, "autotab_windows") == 0)
    {
        CompScreen *s = getScreenFromScreenNum (screenNum);

        GROUP_SCREEN (s);

        int i;
        if (gs->autotab && gs->autotabCount != 0)
        {
            for (i = 0; i <= gs->autotabCount - 1; i++)
                matchFini (&gs->autotab[i]);

            free (gs->autotab);
        }

        gs->autotabCount = optionValue->list.nItem;
        gs->autotab = malloc (gs->autotabCount * sizeof (CompMatch));

        for (i = 0; i <= gs->autotabCount - 1; i++)
        {
            matchInit (&gs->autotab[i]);
            matchAddFromString (&gs->autotab[i], optionValue->list.item[i].s);
            matchUpdate (&gs->autotab[i]);
        }
    }
}
Пример #2
0
static void
decorHandleEvent (CompDisplay *d,
		  XEvent      *event)
{
    Window     activeWindow = d->activeWindow;
    CompWindow *w;

    DECOR_DISPLAY (d);

    switch (event->type) {
    case DestroyNotify:
	w = findWindowAtDisplay (d, event->xdestroywindow.window);
	if (w)
	{
	    DECOR_SCREEN (w->screen);

	    if (w->id == ds->dmWin)
		decorCheckForDmOnScreen (w->screen, TRUE);
	}
	break;
    case MapRequest:
	w = findWindowAtDisplay (d, event->xmaprequest.window);
	if (w)
	    decorWindowUpdate (w, TRUE);
	break;
    case ClientMessage:
	if (event->xclient.message_type == dd->requestFrameExtentsAtom)
	{
	    w = findWindowAtDisplay (d, event->xclient.window);
	    if (w)
		decorWindowUpdate (w, TRUE);
	}
	break;
    default:
	if (event->type == d->damageEvent + XDamageNotify)
	{
	    XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
	    DecorTexture       *t;

	    for (t = dd->textures; t; t = t->next)
	    {
		if (t->pixmap == de->drawable)
		{
		    DecorWindow *dw;
		    DecorScreen *ds;
		    CompScreen  *s;

		    t->texture.oldMipmaps = TRUE;

		    for (s = d->screens; s; s = s->next)
		    {
			ds = GET_DECOR_SCREEN (s, dd);

			for (w = s->windows; w; w = w->next)
			{
			    if (w->shaded || w->mapNum)
			    {
				dw = GET_DECOR_WINDOW (w, ds);

				if (dw->wd && dw->wd->decor->texture == t)
				    damageWindowOutputExtents (w);
			    }
			}
		    }
		    return;
		}
	    }
	}
	break;
    }

    UNWRAP (dd, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (dd, d, handleEvent, decorHandleEvent);

    if (d->activeWindow != activeWindow)
    {
	w = findWindowAtDisplay (d, activeWindow);
	if (w)
	    decorWindowUpdate (w, TRUE);

	w = findWindowAtDisplay (d, d->activeWindow);
	if (w)
	    decorWindowUpdate (w, TRUE);
    }

    switch (event->type) {
    case PropertyNotify:
	if (event->xproperty.atom == dd->winDecorAtom)
	{
	    w = findWindowAtDisplay (d, event->xproperty.window);
	    if (w)
	    {
		decorWindowUpdateDecoration (w);
		decorWindowUpdate (w, TRUE);
	    }
	}
	else if (event->xproperty.atom == d->mwmHintsAtom)
	{
	    w = findWindowAtDisplay (d, event->xproperty.window);
	    if (w)
		decorWindowUpdate (w, TRUE);
	}
	else
	{
	    CompScreen *s;

	    s = findScreenAtDisplay (d, event->xproperty.window);
	    if (s)
	    {
		if (event->xproperty.atom == dd->supportingDmCheckAtom)
		{
		    decorCheckForDmOnScreen (s, TRUE);
		}
		else
		{
		    int i;

		    for (i = 0; i < DECOR_NUM; i++)
		    {
			if (event->xproperty.atom == dd->decorAtom[i])
			{
			    DECOR_SCREEN (s);

			    if (ds->decor[i])
				decorReleaseDecoration (s, ds->decor[i]);

			    ds->decor[i] =
				decorCreateDecoration (s, s->root,
						       dd->decorAtom[i]);

			    for (w = s->windows; w; w = w->next)
				decorWindowUpdate (w, TRUE);
			}
		    }
		}
	    }
	}
	break;
    default:
	if (d->shapeExtension && event->type == d->shapeEvent + ShapeNotify)
	{
	    w = findWindowAtDisplay (d, ((XShapeEvent *) event)->window);
	    if (w)
		decorWindowUpdate (w, TRUE);
	}
	break;
    }
}
Пример #3
0
/*
 * groupDeleteGroup
 *
 */
void
groupDeleteGroup (GroupSelection *group)
{
	GroupSelection *next, *prev;
	CompScreen     *s = group->screen;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);

	if (group->windows)
	{
		int i;

		if (group->tabBar)
		{
			/* set up untabbing animation and delete the group
			   at the end of the animation */
			groupUntabGroup (group);
			group->ungroupState = UngroupAll;
			return;
		}

		for (i = 0; i < group->nWins; i++)
		{
			CompWindow *cw = group->windows[i];
			GROUP_WINDOW (cw);

			damageWindowOutputExtents (cw);
			gw->group = NULL;
			updateWindowOutputExtents (cw);
			groupUpdateWindowProperty (cw);

			const BananaValue *
			option_autotab_create = bananaGetOption (bananaIndex,
			                                         "autotab_create",
			                                         s->screenNum);

			if (option_autotab_create->b && groupIsGroupWindow (cw))
			{
				groupAddWindowToGroup (cw, NULL, 0);
				groupTabGroup (cw);
			}
		}

		free (group->windows);
		group->windows = NULL;
	}
	else if (group->tabBar)
		groupDeleteTabBar (group);

	prev = group->prev;
	next = group->next;

	/* relink stack */
	if (prev || next)
	{
		if (prev)
		{
			if (next)
				prev->next = next;
			else
				prev->next = NULL;
		}
		if (next)
		{
			if (prev)
				next->prev = prev;
			else
			{
				next->prev = NULL;
				gs->groups = next;
			}
		}
	}
	else
		gs->groups = NULL;

	if (group == gs->lastHoveredGroup)
		gs->lastHoveredGroup = NULL;
	if (group == gd->lastRestackedGroup)
		gd->lastRestackedGroup = NULL;

	free (group);
}
Пример #4
0
static Bool
decorWindowUpdate (CompWindow *w,
		   Bool	      allowDecoration)
{
    WindowDecoration *wd;
    Decoration	     *old, *decor = NULL;
    Bool	     decorate = FALSE;
    CompMatch	     *match;
    int		     moveDx, moveDy;
    int		     oldShiftX = 0;
    int		     oldShiftY  = 0;

    DECOR_DISPLAY (w->screen->display);
    DECOR_SCREEN (w->screen);
    DECOR_WINDOW (w);

    wd = dw->wd;
    old = (wd) ? wd->decor : NULL;

    switch (w->type) {
    case CompWindowTypeDialogMask:
    case CompWindowTypeModalDialogMask:
    case CompWindowTypeUtilMask:
    case CompWindowTypeMenuMask:
    case CompWindowTypeNormalMask:
	if (w->mwmDecor & (MwmDecorAll | MwmDecorTitle))
	    decorate = TRUE;
    default:
	break;
    }

    if (w->wmType & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
	decorate = FALSE;

    if (w->attrib.override_redirect)
	decorate = FALSE;

    if (decorate)
    {
	match = &dd->opt[DECOR_DISPLAY_OPTION_DECOR_MATCH].value.match;
	if (!matchEval (match, w))
	    decorate = FALSE;
    }

    if (decorate)
    {
	if (dw->decor && decorCheckSize (w, dw->decor))
	{
	    decor = dw->decor;
	}
	else
	{
	    if (w->id == w->screen->display->activeWindow)
		decor = ds->decor[DECOR_ACTIVE];
	    else
		decor = ds->decor[DECOR_NORMAL];
	}
    }
    else
    {
	match = &dd->opt[DECOR_DISPLAY_OPTION_SHADOW_MATCH].value.match;
	if (matchEval (match, w))
	{
	    if (w->region->numRects == 1)
		decor = ds->decor[DECOR_BARE];

	    if (decor)
	    {
		if (!decorCheckSize (w, decor))
		    decor = NULL;
	    }
	}
    }

    if (!ds->dmWin || !allowDecoration)
	decor = NULL;

    if (decor == old)
	return FALSE;

    damageWindowOutputExtents (w);

    if (old)
    {
	oldShiftX = decorWindowShiftX (w);
	oldShiftY = decorWindowShiftY (w);

	destroyWindowDecoration (w->screen, wd);
    }

    if (decor)
    {
	dw->wd = createWindowDecoration (decor);
	if (!dw->wd)
	    return FALSE;

	if ((w->state & MAXIMIZE_STATE) == MAXIMIZE_STATE)
	    setWindowFrameExtents (w, &decor->maxInput);
	else
	    setWindowFrameExtents (w, &decor->input);

	moveDx = decorWindowShiftX (w) - oldShiftX;
	moveDy = decorWindowShiftY (w) - oldShiftY;

	updateWindowOutputExtents (w);
	damageWindowOutputExtents (w);
	updateWindowDecorationScale (w);
    }
    else
    {
	CompWindowExtents emptyInput;

	memset (&emptyInput, 0, sizeof (emptyInput));
	setWindowFrameExtents (w, &emptyInput);

	dw->wd = NULL;

	moveDx = -oldShiftX;
	moveDy = -oldShiftY;
    }

    if (w->placed && !w->attrib.override_redirect && (moveDx || moveDy))
    {
	XWindowChanges xwc;
	unsigned int   mask = CWX | CWY;

	xwc.x = w->serverX + moveDx;
	xwc.y = w->serverY + moveDy;

	if (w->state & CompWindowStateFullscreenMask)
	    mask &= ~(CWX | CWY);

	if (w->state & CompWindowStateMaximizedHorzMask)
	    mask &= ~CWX;

	if (w->state & CompWindowStateMaximizedVertMask)
	    mask &= ~CWY;

	if (w->saveMask & CWX)
	    w->saveWc.x += moveDx;

	if (w->saveMask & CWY)
	    w->saveWc.y += moveDy;

	if (mask)
	    configureXWindow (w, mask, &xwc);
    }

    return TRUE;
}
Пример #5
0
/*
 * groupDeleteGroupWindow
 *
 */
void
groupDeleteGroupWindow (CompWindow *w)
{
	GroupSelection *group;

	GROUP_WINDOW (w);
	GROUP_SCREEN (w->screen);

	if (!gw->group)
		return;

	group = gw->group;

	if (group->tabBar && gw->slot)
	{
		if (gs->draggedSlot && gs->dragged &&
		    gs->draggedSlot->window->id == w->id)
		{
			groupUnhookTabBarSlot (group->tabBar, gw->slot, FALSE);
		}
		else
			groupDeleteTabBarSlot (group->tabBar, gw->slot);
	}

	if (group->nWins && group->windows)
	{
		CompWindow **buf = group->windows;

		if (group->nWins > 1)
		{
			int counter = 0;
			int i;

			group->windows = calloc (group->nWins - 1, sizeof(CompWindow *));

			for (i = 0; i < group->nWins; i++)
			{
				if (buf[i]->id == w->id)
					continue;
				group->windows[counter++] = buf[i];
			}
			group->nWins = counter;

			if (group->nWins == 1)
			{
				/* Glow was removed from this window, too */
				damageWindowOutputExtents (group->windows[0]);
				updateWindowOutputExtents (group->windows[0]);

				const BananaValue *
				option_auto_ungroup = bananaGetOption (bananaIndex,
				                                       "auto_ungroup",
				                                       w->screen->screenNum);

				if (option_auto_ungroup->b)
				{
					if (group->changeState != NoTabChange)
					{
						/* a change animation is pending: this most
						   likely means that a window must be moved
						   back onscreen, so we do that here */
						CompWindow *lw = group->windows[0];

						groupSetWindowVisibility (lw, TRUE);
					}

					const BananaValue *
					option_autotab_create = bananaGetOption (bananaIndex,
					                                       "autotab_create",
					                                    w->screen->screenNum);

					if (!option_autotab_create->b)
						groupDeleteGroup (group);
				}
			}
		}
		else
		{
			group->windows = NULL;
			groupDeleteGroup (group);
		}

		free (buf);

		damageWindowOutputExtents (w);
		gw->group = NULL;
		updateWindowOutputExtents (w);
		groupUpdateWindowProperty (w);
	}
}