Пример #1
0
/*
 * groupUpdateWindowProperty
 *
 */
void
groupUpdateWindowProperty (CompWindow *w)
{
	CompDisplay *d = &display;

	GROUP_WINDOW (w);
	GROUP_DISPLAY (d);

	// Do not change anything in this case
	if (gw->readOnlyProperty)
		return;

	if (gw->group)
	{
		long int buffer[5];

		buffer[0] = gw->group->identifier;
		buffer[1] = (gw->slot) ? TRUE : FALSE;

		/* group color RGB */
		buffer[2] = gw->group->color[0];
		buffer[3] = gw->group->color[1];
		buffer[4] = gw->group->color[2];

		XChangeProperty (d->display, w->id, gd->groupWinPropertyAtom,
		                 XA_CARDINAL, 32, PropModeReplace,
		                 (unsigned char *) buffer, 5);
	}
	else
	{
		XDeleteProperty (d->display, w->id, gd->groupWinPropertyAtom);
	}
}
Пример #2
0
/*
 * groupUnsetIgnore
 *
 */
Bool
groupUnsetIgnore (void)
{
	GROUP_DISPLAY (&display);

	gd->ignoreMode = FALSE;

	return FALSE;
}
Пример #3
0
/*
 * groupFiniDisplay
 *
 */
static void
groupFiniDisplay (CompPlugin  *p,
                  CompDisplay *d)
{
    GROUP_DISPLAY (d);

    freeScreenPrivateIndex (gd->screenPrivateIndex);

    UNWRAP (gd, d, handleEvent);

    free (gd);
}
Пример #4
0
/*
 * groupGetOutputExtentsForWindow
 *
 */
void
groupGetOutputExtentsForWindow (CompWindow        *w,
                                CompWindowExtents *output)
{
	GROUP_SCREEN (w->screen);
	GROUP_WINDOW (w);

	UNWRAP (gs, w->screen, getOutputExtentsForWindow);
	(*w->screen->getOutputExtentsForWindow)(w, output);
	WRAP (gs, w->screen, getOutputExtentsForWindow,
	      groupGetOutputExtentsForWindow);

	if (gw->group && gw->group->nWins > 1)
	{
		GROUP_DISPLAY (&display);

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

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

		int glowSize = option_glow_size->i;
		int glowType = option_glow_type->i;
		int glowTextureSize = gd->glowTextureProperties[glowType].textureSize;
		int glowOffset = gd->glowTextureProperties[glowType].glowOffset;

		glowSize = glowSize * (glowTextureSize - glowOffset) / glowTextureSize;

		/* glowSize is the size of the glow outside the window decoration
		 * (w->input), while w->output includes the size of w->input
		 * this is why we have to add w->input here */
		output->left   = MAX (output->left, glowSize + w->input.left);
		output->right  = MAX (output->right, glowSize + w->input.right);
		output->top    = MAX (output->top, glowSize + w->input.top);
		output->bottom = MAX (output->bottom, glowSize + w->input.bottom);
	}
}
Пример #5
0
/*
 * groupCheckWindowProperty
 *
 */
Bool
groupCheckWindowProperty (CompWindow *w,
                          long int   *id,
                          Bool       *tabbed,
                          GLushort   *color)
{
	Atom type;
	int retval, fmt;
	unsigned long nitems, exbyte;
	long int      *data;

	GROUP_DISPLAY (&display);

	retval = XGetWindowProperty (display.display, w->id,
	                             gd->groupWinPropertyAtom, 0, 5, False,
	                             XA_CARDINAL, &type, &fmt, &nitems, &exbyte,
	                             (unsigned char **)&data);

	if (retval == Success)
	{
		if (type == XA_CARDINAL && fmt == 32 && nitems == 5)
		{
			if (id)
				*id = data[0];
			if (tabbed)
				*tabbed = (Bool) data[1];
			if (color) {
				color[0] = (GLushort) data[2];
				color[1] = (GLushort) data[3];
				color[2] = (GLushort) data[4];
			}

			XFree (data);
			return TRUE;
		}
		else if (fmt != 0)
			XFree (data);
	}

	return FALSE;
}
Пример #6
0
void
groupWindowStateChangeNotify (CompWindow   *w,
                              unsigned int lastState)
{
	CompScreen *s = w->screen;

	GROUP_DISPLAY (&display);
	GROUP_SCREEN (s);
	GROUP_WINDOW (w);

	if (gw->group && !gd->ignoreMode)
	{
		const BananaValue *
		option_maximize_unmaximize_all = bananaGetOption (bananaIndex,
		                                            "maximize_unmaximize_all",
		                                            s->screenNum);

		if (((lastState & MAXIMIZE_STATE) != (w->state & MAXIMIZE_STATE)) &&
		    option_maximize_unmaximize_all->b)
		{
			int i;
			for (i = 0; i < gw->group->nWins; i++)
			{
				CompWindow *cw = gw->group->windows[i];
				if (!cw)
					continue;

				if (cw->id == w->id)
					continue;

				maximizeWindow (cw, w->state & MAXIMIZE_STATE);
			}
		}
	}

	UNWRAP (gs, s, windowStateChangeNotify);
	(*s->windowStateChangeNotify)(w, lastState);
	WRAP (gs, s, windowStateChangeNotify, groupWindowStateChangeNotify);
}
Пример #7
0
/*
 * groupInitScreen
 *
 */
static Bool
groupInitScreen (CompPlugin *p,
                 CompScreen *s)
{
    GroupScreen       *gs;
    int glowType;

    GROUP_DISPLAY (&display);

    gs = malloc (sizeof (GroupScreen));
    if (!gs)
        return FALSE;

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

    WRAP (gs, s, windowMoveNotify, groupWindowMoveNotify);
    WRAP (gs, s, windowResizeNotify, groupWindowResizeNotify);
    WRAP (gs, s, getOutputExtentsForWindow, groupGetOutputExtentsForWindow);
    WRAP (gs, s, preparePaintScreen, groupPreparePaintScreen);
    WRAP (gs, s, paintOutput, groupPaintOutput);
    WRAP (gs, s, drawWindow, groupDrawWindow);
    WRAP (gs, s, paintWindow, groupPaintWindow);
    WRAP (gs, s, paintTransformedOutput, groupPaintTransformedOutput);
    WRAP (gs, s, donePaintScreen, groupDonePaintScreen);
    WRAP (gs, s, windowGrabNotify, groupWindowGrabNotify);
    WRAP (gs, s, windowUngrabNotify, groupWindowUngrabNotify);
    WRAP (gs, s, damageWindowRect, groupDamageWindowRect);
    WRAP (gs, s, windowStateChangeNotify, groupWindowStateChangeNotify);
    WRAP (gs, s, activateWindow, groupActivateWindow);

    s->privates[gd->screenPrivateIndex].ptr = gs;

    gs->groups = NULL;

    gs->tmpSel.windows = NULL;
    gs->tmpSel.nWins   = 0;

    gs->grabIndex = 0;
    gs->grabState = ScreenGrabNone;

    gs->lastHoveredGroup = NULL;

    gs->queued          = FALSE;
    gs->pendingMoves    = NULL;
    gs->pendingGrabs    = NULL;
    gs->pendingUngrabs  = NULL;

    gs->dequeueTimeoutHandle = 0;

    gs->draggedSlot            = NULL;
    gs->dragged                = FALSE;
    gs->dragHoverTimeoutHandle = 0;

    gs->prevX = 0;
    gs->prevY = 0;

    gs->showDelayTimeoutHandle = 0;

    /* one-shot timeout for stuff that needs to be initialized after
       all screens and windows are initialized */
    gs->initialActionsTimeoutHandle =
        compAddTimeout (0, 0, groupApplyInitialActions, (void *) s);

    initTexture (s, &gs->glowTexture);

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

    glowType = option_glow_type->i;
    imageDataToTexture (s, &gs->glowTexture,
                        glowTextureProperties[glowType].textureData,
                        glowTextureProperties[glowType].textureSize,
                        glowTextureProperties[glowType].textureSize,
                        GL_RGBA, GL_UNSIGNED_BYTE);

    const BananaValue *
    option_window_match = bananaGetOption (bananaIndex,
                                           "window_match",
                                           s->screenNum);

    matchInit (&gs->window_match);
    matchAddFromString (&gs->window_match, option_window_match->s);
    matchUpdate (&gs->window_match);

    const BananaValue *
    option_autotab_windows = bananaGetOption (bananaIndex,
                             "autotab_windows",
                             s->screenNum);

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

    int i;
    for (i = 0; i <= gs->autotabCount - 1; i++)
    {
        matchInit (&gs->autotab[i]);
        matchAddFromString (&gs->autotab[i],
                            option_autotab_windows->list.item[i].s);
        matchUpdate (&gs->autotab[i]);
    }

    return TRUE;
}
Пример #8
0
void
groupComputeGlowQuads (CompWindow *w,
                       CompMatrix *matrix)
{
	BoxRec            *box;
	CompMatrix        *quadMatrix;
	int glowSize, glowOffset;
	int glowType;

	GROUP_WINDOW (w);

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

	if (option_glow->b && matrix)
	{
		if (!gw->glowQuads)
			gw->glowQuads = malloc (NUM_GLOWQUADS * sizeof (GlowQuad));
		if (!gw->glowQuads)
			return;
	}
	else
	{
		if (gw->glowQuads)
		{
			free (gw->glowQuads);
			gw->glowQuads = NULL;
		}
		return;
	}

	GROUP_DISPLAY (&display);

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

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

	glowSize = option_glow_size->i;
	glowType = option_glow_type->i;
	glowOffset = (glowSize * gd->glowTextureProperties[glowType].glowOffset /
	              gd->glowTextureProperties[glowType].textureSize) + 1;

	/* Top left corner */
	box = &gw->glowQuads[GLOWQUAD_TOPLEFT].box;
	gw->glowQuads[GLOWQUAD_TOPLEFT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_TOPLEFT].matrix;

	box->x1 = WIN_REAL_X (w) - glowSize + glowOffset;
	box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
	box->x2 = WIN_REAL_X (w) + glowOffset;
	box->y2 = WIN_REAL_Y (w) + glowOffset;

	quadMatrix->xx = 1.0f / glowSize;
	quadMatrix->yy = -1.0f / glowSize;
	quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
	quadMatrix->y0 = 1.0 -(box->y1 * quadMatrix->yy);

	box->x2 = MIN (WIN_REAL_X (w) + glowOffset,
	               WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
	box->y2 = MIN (WIN_REAL_Y (w) + glowOffset,
	               WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));

	/* Top right corner */
	box = &gw->glowQuads[GLOWQUAD_TOPRIGHT].box;
	gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix;

	box->x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
	box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
	box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
	box->y2 = WIN_REAL_Y (w) + glowOffset;

	quadMatrix->xx = -1.0f / glowSize;
	quadMatrix->yy = -1.0f / glowSize;
	quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
	quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy);

	box->x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
	               WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
	box->y2 = MIN (WIN_REAL_Y (w) + glowOffset,
	               WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));

	/* Bottom left corner */
	box = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].box;
	gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix;

	box->x1 = WIN_REAL_X (w) - glowSize + glowOffset;
	box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
	box->x2 = WIN_REAL_X (w) + glowOffset;
	box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;

	quadMatrix->xx = 1.0f / glowSize;
	quadMatrix->yy = 1.0f / glowSize;
	quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
	quadMatrix->y0 = -(box->y1 * quadMatrix->yy);

	box->y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
	               WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
	box->x2 = MIN (WIN_REAL_X (w) + glowOffset,
	               WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));

	/* Bottom right corner */
	box = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].box;
	gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix;

	box->x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
	box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
	box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
	box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;

	quadMatrix->xx = -1.0f / glowSize;
	quadMatrix->yy = 1.0f / glowSize;
	quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
	quadMatrix->y0 = -(box->y1 * quadMatrix->yy);

	box->x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
	               WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
	box->y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
	               WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));

	/* Top edge */
	box = &gw->glowQuads[GLOWQUAD_TOP].box;
	gw->glowQuads[GLOWQUAD_TOP].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_TOP].matrix;

	box->x1 = WIN_REAL_X (w) + glowOffset;
	box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
	box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
	box->y2 = WIN_REAL_Y (w) + glowOffset;

	quadMatrix->xx = 0.0f;
	quadMatrix->yy = -1.0f / glowSize;
	quadMatrix->x0 = 1.0;
	quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy);

	/* Bottom edge */
	box = &gw->glowQuads[GLOWQUAD_BOTTOM].box;
	gw->glowQuads[GLOWQUAD_BOTTOM].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOM].matrix;

	box->x1 = WIN_REAL_X (w) + glowOffset;
	box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
	box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
	box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;

	quadMatrix->xx = 0.0f;
	quadMatrix->yy = 1.0f / glowSize;
	quadMatrix->x0 = 1.0;
	quadMatrix->y0 = -(box->y1 * quadMatrix->yy);

	/* Left edge */
	box = &gw->glowQuads[GLOWQUAD_LEFT].box;
	gw->glowQuads[GLOWQUAD_LEFT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_LEFT].matrix;

	box->x1 = WIN_REAL_X (w) - glowSize + glowOffset;
	box->y1 = WIN_REAL_Y (w) + glowOffset;
	box->x2 = WIN_REAL_X (w) + glowOffset;
	box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;

	quadMatrix->xx = 1.0f / glowSize;
	quadMatrix->yy = 0.0f;
	quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
	quadMatrix->y0 = 0.0;

	/* Right edge */
	box = &gw->glowQuads[GLOWQUAD_RIGHT].box;
	gw->glowQuads[GLOWQUAD_RIGHT].matrix = *matrix;
	quadMatrix = &gw->glowQuads[GLOWQUAD_RIGHT].matrix;

	box->x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
	box->y1 = WIN_REAL_Y (w) + glowOffset;
	box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
	box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;

	quadMatrix->xx = -1.0f / glowSize;
	quadMatrix->yy = 0.0f;
	quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
	quadMatrix->y0 = 0.0;
}
Пример #9
0
/*
 * groupPaintOutput
 *
 */
Bool
groupPaintOutput (CompScreen              *s,
                  const ScreenPaintAttrib *sAttrib,
                  const CompTransform     *transform,
                  Region                  region,
                  CompOutput              *output,
                  unsigned int            mask)
{
	GroupSelection *group;
	Bool status;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);

	gs->painted = FALSE;
	gs->vpX = s->x;
	gs->vpY = s->y;

	if (gd->resizeInfo)
	{
		mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
	}
	else
	{
		for (group = gs->groups; group; group = group->next)
		{
			if (group->changeState != NoTabChange ||
			    group->tabbingState != NoTabbing)
			{
				mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
			}
			else if (group->tabBar && (group->tabBar->state != PaintOff))
			{
				mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
			}
		}
	}

	UNWRAP (gs, s, paintOutput);
	status = (*s->paintOutput)(s, sAttrib, transform, region, output, mask);
	WRAP (gs, s, paintOutput, groupPaintOutput);

	if (status && !gs->painted)
	{
		if ((gs->grabState == ScreenGrabTabDrag) && gs->draggedSlot)
		{
			CompTransform wTransform = *transform;
			PaintState state;

			GROUP_WINDOW (gs->draggedSlot->window);

			transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &wTransform);

			glPushMatrix ();
			glLoadMatrixf (wTransform.m);

			/* prevent tab bar drawing.. */
			state = gw->group->tabBar->state;
			gw->group->tabBar->state = PaintOff;
			groupPaintThumb (NULL, gs->draggedSlot, &wTransform, OPAQUE);
			gw->group->tabBar->state = state;

			glPopMatrix ();
		}
		else if (gs->grabState == ScreenGrabSelect)
		{
			groupPaintSelectionOutline (s, sAttrib, transform, output, FALSE);
		}
	}

	return status;
}
Пример #10
0
void
groupWindowUngrabNotify (CompWindow *w)
{
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	if (gw->group && !gd->ignoreMode && !gs->queued)
	{
		int i;
		XRectangle rect;

		groupDequeueMoveNotifies (s);

		if (gd->resizeInfo)
		{
			rect.x      = WIN_X (w);
			rect.y      = WIN_Y (w);
			rect.width  = WIN_WIDTH (w);
			rect.height = WIN_HEIGHT (w);
		}

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

			if (cw->id != w->id)
			{
				GROUP_WINDOW (cw);

				if (gw->resizeGeometry)
				{
					unsigned int mask;

					gw->resizeGeometry->x      = WIN_X (cw);
					gw->resizeGeometry->y      = WIN_Y (cw);
					gw->resizeGeometry->width  = WIN_WIDTH (cw);
					gw->resizeGeometry->height = WIN_HEIGHT (cw);

					mask = groupUpdateResizeRectangle (cw, &rect, FALSE);
					if (mask)
					{
						XWindowChanges xwc;
						xwc.x      = gw->resizeGeometry->x;
						xwc.y      = gw->resizeGeometry->y;
						xwc.width  = gw->resizeGeometry->width;
						xwc.height = gw->resizeGeometry->height;

						if (w->mapNum && (mask & (CWWidth | CWHeight)))
							sendSyncRequest (w);

						configureXWindow (cw, mask, &xwc);
					}
					else
					{
						free (gw->resizeGeometry);
						gw->resizeGeometry =  NULL;
					}
				}
				if (gw->needsPosSync)
				{
					syncWindowPosition (cw);
					gw->needsPosSync = FALSE;
				}
				groupEnqueueUngrabNotify (cw);
			}
		}

		if (gd->resizeInfo)
		{
			free (gd->resizeInfo);
			gd->resizeInfo = NULL;
		}

		gw->group->grabWindow = None;
		gw->group->grabMask = 0;
	}

	UNWRAP (gs, s, windowUngrabNotify);
	(*s->windowUngrabNotify)(w);
	WRAP ( gs, s, windowUngrabNotify, groupWindowUngrabNotify);
}
Пример #11
0
void
groupWindowGrabNotify (CompWindow   *w,
                       int          x,
                       int          y,
                       unsigned int state,
                       unsigned int mask)
{
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	if (gw->group && !gd->ignoreMode && !gs->queued)
	{
		Bool doResizeAll;
		int i;

		const BananaValue *
		option_resize_all = bananaGetOption (bananaIndex,
		                                     "resize_all",
		                                     s->screenNum);

		doResizeAll = option_resize_all->b &&
		              (mask & CompWindowGrabResizeMask);

		if (gw->group->tabBar)
			groupTabSetVisibility (gw->group, FALSE, 0);

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

			if (cw->id != w->id)
			{
				GroupWindow *gcw = GET_GROUP_WINDOW (cw, gs);

				groupEnqueueGrabNotify (cw, x, y, state, mask);

				if (doResizeAll && !(cw->state & MAXIMIZE_STATE))
				{
					if (!gcw->resizeGeometry)
						gcw->resizeGeometry = malloc (sizeof (XRectangle));
					if (gcw->resizeGeometry)
					{
						gcw->resizeGeometry->x      = WIN_X (cw);
						gcw->resizeGeometry->y      = WIN_Y (cw);
						gcw->resizeGeometry->width  = WIN_WIDTH (cw);
						gcw->resizeGeometry->height = WIN_HEIGHT (cw);
					}
				}
			}
		}

		if (doResizeAll)
		{
			if (!gd->resizeInfo)
				gd->resizeInfo = malloc (sizeof (GroupResizeInfo));

			if (gd->resizeInfo)
			{
				gd->resizeInfo->resizedWindow       = w;
				gd->resizeInfo->origGeometry.x      = WIN_X (w);
				gd->resizeInfo->origGeometry.y      = WIN_Y (w);
				gd->resizeInfo->origGeometry.width  = WIN_WIDTH (w);
				gd->resizeInfo->origGeometry.height = WIN_HEIGHT (w);
			}
		}

		gw->group->grabWindow = w->id;
		gw->group->grabMask = mask;
	}

	UNWRAP (gs, s, windowGrabNotify);
	(*s->windowGrabNotify)(w, x, y, state, mask);
	WRAP (gs, s, windowGrabNotify, groupWindowGrabNotify);
}
Пример #12
0
/*
 * groupWindowMoveNotify
 *
 */
void
groupWindowMoveNotify (CompWindow *w,
                       int        dx,
                       int        dy,
                       Bool       immediate)
{
	CompScreen *s = w->screen;
	Bool viewportChange;
	int i;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	UNWRAP (gs, s, windowMoveNotify);
	(*s->windowMoveNotify)(w, dx, dy, immediate);
	WRAP (gs, s, windowMoveNotify, groupWindowMoveNotify);

	if (gw->glowQuads)
		groupComputeGlowQuads (w, &gs->glowTexture.matrix);

	if (!gw->group || gs->queued)
		return;

	/* FIXME: we need a reliable, 100% safe way to detect window
	   moves caused by viewport changes here */
	viewportChange = ((dx && !(dx % w->screen->width)) ||
	                  (dy && !(dy % w->screen->height)));

	if (viewportChange && (gw->animateState & IS_ANIMATED))
	{
		gw->destination.x += dx;
		gw->destination.y += dy;
	}

	if (gw->group->tabBar && IS_TOP_TAB (w, gw->group))
	{
		GroupTabBarSlot *slot;
		GroupTabBar     *bar = gw->group->tabBar;

		bar->rightSpringX += dx;
		bar->leftSpringX += dx;

		groupMoveTabBarRegion (gw->group, dx, dy, TRUE);

		for (slot = bar->slots; slot; slot = slot->next)
		{
			XOffsetRegion (slot->region, dx, dy);
			slot->springX += dx;
		}
	}

	const BananaValue *
	option_move_all = bananaGetOption (bananaIndex,
	                                   "move_all",
	                                   s->screenNum);

	if (!option_move_all->b || gd->ignoreMode ||
	    (gw->group->tabbingState != NoTabbing) ||
	    (gw->group->grabWindow != w->id) ||
	    !(gw->group->grabMask & CompWindowGrabMoveMask))
	{
		return;
	}

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

		if (cw->id == w->id)
			continue;

		GROUP_WINDOW (cw);

		if (cw->state & MAXIMIZE_STATE)
		{
			if (viewportChange)
				groupEnqueueMoveNotify (cw, -dx, -dy, immediate, TRUE);
		}
		else if (!viewportChange)
		{
			gw->needsPosSync = TRUE;
			groupEnqueueMoveNotify (cw, dx, dy, immediate, FALSE);
		}
	}
}
Пример #13
0
static unsigned int
groupUpdateResizeRectangle (CompWindow *w,
                            XRectangle *masterGeometry,
                            Bool       damage)
{
	XRectangle newGeometry;
	unsigned int mask = 0;
	int newWidth, newHeight;
	int widthDiff, heightDiff;

	GROUP_WINDOW (w);
	GROUP_DISPLAY (&display);

	if (!gw->resizeGeometry || !gd->resizeInfo)
		return 0;

	newGeometry.x = WIN_X (w) + (masterGeometry->x -
	                             gd->resizeInfo->origGeometry.x);
	newGeometry.y = WIN_Y (w) + (masterGeometry->y -
	                             gd->resizeInfo->origGeometry.y);

	widthDiff = masterGeometry->width - gd->resizeInfo->origGeometry.width;
	newGeometry.width = MAX (1, WIN_WIDTH (w) + widthDiff);
	heightDiff = masterGeometry->height - gd->resizeInfo->origGeometry.height;
	newGeometry.height = MAX (1, WIN_HEIGHT (w) + heightDiff);

	if (constrainNewWindowSize (w,
	                            newGeometry.width, newGeometry.height,
	                            &newWidth, &newHeight))
	{

		newGeometry.width  = newWidth;
		newGeometry.height = newHeight;
	}

	if (damage)
	{
		if (memcmp (&newGeometry, gw->resizeGeometry,
		            sizeof (newGeometry)) != 0)
		{
			addWindowDamage (w);
		}
	}

	if (newGeometry.x != gw->resizeGeometry->x)
	{
		gw->resizeGeometry->x = newGeometry.x;
		mask |= CWX;
	}
	if (newGeometry.y != gw->resizeGeometry->y)
	{
		gw->resizeGeometry->y = newGeometry.y;
		mask |= CWY;
	}
	if (newGeometry.width != gw->resizeGeometry->width)
	{
		gw->resizeGeometry->width = newGeometry.width;
		mask |= CWWidth;
	}
	if (newGeometry.height != gw->resizeGeometry->height)
	{
		gw->resizeGeometry->height = newGeometry.height;
		mask |= CWHeight;
	}

	return mask;
}
Пример #14
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]);
        }
    }
}
Пример #15
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);
}
Пример #16
0
/*
 * groupRenderWindowTitle
 *
 */
void
groupRenderWindowTitle (GroupSelection *group)
{
    GroupCairoLayer *layer;
    int             width, height;
    Pixmap          pixmap = None;
    CompScreen      *s = group->screen;
    CompDisplay     *d = s->display;
    GroupTabBar     *bar = group->tabBar;

    GROUP_DISPLAY (d);

    if (!bar || !HAS_TOP_WIN (group) || !bar->textLayer)
	return;

    width = bar->region->extents.x2 - bar->region->extents.x1;
    height = bar->region->extents.y2 - bar->region->extents.y1;

    bar->textLayer = groupRebuildCairoLayer (s, bar->textLayer, width, height);
    layer = bar->textLayer;
    if (!layer)
	return;

    if (bar->textSlot && bar->textSlot->window && gd->textFunc)
    {
	CompTextData    *data;
	CompTextAttrib  textAttrib;

	textAttrib.family = groupGetTabbarFontFamily(s);
	textAttrib.size   = groupGetTabbarFontSize (s);

	textAttrib.flags = CompTextFlagStyleBold | CompTextFlagEllipsized |
	                   CompTextFlagNoAutoBinding;

	textAttrib.color[0] = groupGetTabbarFontColorRed (s);
	textAttrib.color[1] = groupGetTabbarFontColorGreen (s);
	textAttrib.color[2] = groupGetTabbarFontColorBlue (s);
	textAttrib.color[3] = groupGetTabbarFontColorAlpha (s);

	textAttrib.maxWidth = width;
	textAttrib.maxHeight = height;

	data = (gd->textFunc->renderWindowTitle) (s, bar->textSlot->window->id,
						  FALSE, &textAttrib);
	if (data)
	{
	    pixmap = data->pixmap;
	    width = data->width;
	    height = data->height;
	    free (data);
	}
    }

    if (!pixmap)
    {
	/* getting the pixmap failed, so create an empty one */
	pixmap = XCreatePixmap (d->display, s->root, width, height, 32);

	if (pixmap)
	{
	    XGCValues gcv;
	    GC        gc;

	    gcv.foreground = 0x00000000;
	    gcv.plane_mask = 0xffffffff;

	    gc = XCreateGC (d->display, pixmap, GCForeground, &gcv);
	    XFillRectangle (d->display, pixmap, gc, 0, 0, width, height);
	    XFreeGC (d->display, gc);
	}
    }

    layer->texWidth = width;
    layer->texHeight = height;

    if (pixmap)
    {
	layer->pixmap = pixmap;
	bindPixmapToTexture (s, &layer->texture, layer->pixmap,
			     layer->texWidth, layer->texHeight, 32);
    }
}
Пример #17
0
/*
 * groupHandleEvent
 *
 */
void
groupHandleEvent (XEvent *event)
{
	CompWindow *w;
	CompScreen *s;

	GROUP_DISPLAY (&display);

	switch (event->type) {
	case KeyPress:
		if (isKeyPressEvent (event, &gd->select_single_key))
			groupSelectSingle (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->group_key))
			groupGroupWindows (event->xkey.root);

		else if (isKeyPressEvent (event, &gd->ungroup_key))
			groupUnGroupWindows (event->xkey.root);

		else if (isKeyPressEvent (event, &gd->remove_key))
			groupRemoveWindow (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->close_key))
			groupCloseWindows (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->ignore_key))
			groupSetIgnore ();

		else if (isKeyPressEvent (event, &gd->tabmode_key))
			groupInitTab (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->change_tab_left_key))
			groupChangeTabLeft (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->change_tab_right_key))
			groupChangeTabRight (display.activeWindow);

		else if (isKeyPressEvent (event, &gd->change_color_key))
			groupChangeColor (display.activeWindow);

		break;
	case KeyRelease:
		if (gd->ignore_key.keycode == event->xkey.keycode)
			groupUnsetIgnore ();
		break;

	case MotionNotify:
		s = findScreenAtDisplay (event->xmotion.root);
		if (s)
			groupHandleMotionEvent (s, pointerX, pointerY);
		break;

	case ButtonPress:
		if (isButtonPressEvent (event, &gd->select_button))
			groupSelect (event->xbutton.window);

		s = findScreenAtDisplay (event->xbutton.root);
		if (s)
			groupHandleButtonPressEvent (s, event);
		break;

	case ButtonRelease:
		if (gd->select_button.button == event->xbutton.button)
			groupSelectTerminate (event->xbutton.root);

		s = findScreenAtDisplay (event->xbutton.root);
		if (s)
			groupHandleButtonReleaseEvent (s, event);
		break;

	case MapNotify:
		w = findWindowAtDisplay (event->xmap.window);
		if (w)
		{
			CompWindow *cw;
			for (cw = w->screen->windows; cw; cw = cw->next)
			{
				if (w->id == cw->frame)
				{
					GROUP_WINDOW (cw);
					if (gw->windowHideInfo)
						XUnmapWindow (display.display, cw->frame);
				}
			}
		}
		break;

	case UnmapNotify:
		w = findWindowAtDisplay (event->xunmap.window);
		if (w)
		{
			GROUP_WINDOW (w);

			if (w->pendingUnmaps)
			{
				if (w->shaded)
				{
					gw->windowState = WindowShaded;

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

					if (gw->group && option_shade_all->b)
						groupShadeWindows (w, gw->group, TRUE);
				}
				else if (w->minimized)
				{
					gw->windowState = WindowMinimized;

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

					if (gw->group && option_minimize_all->b)
						groupMinimizeWindows (w, gw->group, TRUE);
				}
			}

			if (gw->group)
			{
				if (gw->group->tabBar && IS_TOP_TAB (w, gw->group))
				{
					/* on unmap of the top tab, hide the tab bar and the
					   input prevention window */
					groupTabSetVisibility (gw->group, FALSE, PERMANENT);
				}
				if (!w->pendingUnmaps)
				{
					/* close event */
					if (!(gw->animateState & IS_UNGROUPING))
					{
						groupDeleteGroupWindow (w);
						damageScreen (w->screen);
					}
				}
			}
		}
		break;

	case ClientMessage:
		if (event->xclient.message_type == display.winActiveAtom)
		{
			w = findWindowAtDisplay (event->xclient.window);
			if (w)
			{
				GROUP_WINDOW (w);

				if (gw->group && gw->group->tabBar &&
				    !IS_TOP_TAB (w, gw->group))
				{
					gw->group->checkFocusAfterTabChange = TRUE;
					groupChangeTab (gw->slot, RotateUncertain);
				}
			}
		}
		else if (event->xclient.message_type == gd->resizeNotifyAtom)
		{
			CompWindow *w;
			w = findWindowAtDisplay (event->xclient.window);

			if (w && gd->resizeInfo && (w == gd->resizeInfo->resizedWindow))
			{
				GROUP_WINDOW (w);
				GROUP_SCREEN (w->screen);

				if (gw->group)
				{
					int i;
					XRectangle rect;

					rect.x      = event->xclient.data.l[0];
					rect.y      = event->xclient.data.l[1];
					rect.width  = event->xclient.data.l[2];
					rect.height = event->xclient.data.l[3];

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

						gcw = GET_GROUP_WINDOW (cw, gs);
						if (gcw->resizeGeometry)
						{
							if (groupUpdateResizeRectangle (cw, &rect, TRUE))
								addWindowDamage (cw);
						}
					}
				}
			}
		}
		break;

	default:
		if (event->type == display.shapeEvent + ShapeNotify)
		{
			XShapeEvent *se = (XShapeEvent *) event;
			if (se->kind == ShapeInput)
			{
				CompWindow *w;
				w = findWindowAtDisplay (se->window);
				if (w)
				{
					GROUP_WINDOW (w);

					if (gw->windowHideInfo)
						groupClearWindowInputShape (w, gw->windowHideInfo);
				}
			}
		}
		break;
	}

	UNWRAP (gd, &display, handleEvent);
	(*display.handleEvent)(event);
	WRAP (gd, &display, handleEvent, groupHandleEvent);

	switch (event->type) {
	case PropertyNotify:
		if (event->xproperty.atom == display.wmNameAtom)
		{
			CompWindow *w;
			w = findWindowAtDisplay (event->xproperty.window);
			if (w)
			{
				GROUP_WINDOW (w);

				if (gw->group && gw->group->tabBar &&
				    gw->group->tabBar->textSlot    &&
				    gw->group->tabBar->textSlot->window == w)
				{
					/* make sure we are using the updated name */
					groupRenderWindowTitle (gw->group);
					groupDamageTabBarRegion (gw->group);
				}
			}
		}
		break;

	case EnterNotify:
	{
		CompWindow *w;
		w = findWindowAtDisplay (event->xcrossing.window);
		if (w)
		{
			GROUP_WINDOW (w);
			GROUP_SCREEN (w->screen);

			if (gs->showDelayTimeoutHandle)
				compRemoveTimeout (gs->showDelayTimeoutHandle);

			if (w->id != w->screen->grabWindow)
				groupUpdateTabBars (w->screen, w->id);

			if (gw->group)
			{
				if (gs->draggedSlot && gs->dragged &&
				    IS_TOP_TAB (w, gw->group))
				{
					int hoverTime;

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

					hoverTime = option_drag_hover_time->f * 1000;
					if (gs->dragHoverTimeoutHandle)
						compRemoveTimeout (gs->dragHoverTimeoutHandle);

					if (hoverTime > 0)
						gs->dragHoverTimeoutHandle =
						        compAddTimeout (hoverTime,
						                        (float) hoverTime * 1.2,
						                        groupDragHoverTimeout, w);
				}
			}
		}
	}
	break;

	case ConfigureNotify:
	{
		CompWindow *w;

		w = findWindowAtDisplay (event->xconfigure.window);
		if (w)
		{
			GROUP_WINDOW (w);

			if (gw->group && gw->group->tabBar &&
			    IS_TOP_TAB (w, gw->group)      &&
			    gw->group->inputPrevention && gw->group->ipwMapped)
			{
				XWindowChanges xwc;

				xwc.stack_mode = Above;
				xwc.sibling = w->id;

				XConfigureWindow (display.display,
				                  gw->group->inputPrevention,
				                  CWSibling | CWStackMode, &xwc);
			}

			if (event->xconfigure.above != None)
			{
				if (gw->group && !gw->group->tabBar &&
				    (gw->group != gd->lastRestackedGroup))
				{
					const BananaValue *
					option_raise_all = bananaGetOption (bananaIndex,
					                                    "raise_all",
					                                    w->screen->screenNum);

					if (option_raise_all->b)
						groupRaiseWindows (w, gw->group);
				}
				if (w->managed && !w->attrib.override_redirect)
					gd->lastRestackedGroup = gw->group;
			}
		}
	}
	break;

	default:
		break;
	}
}