All pastes #382239 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-03-05 13:08 UTC
rendered paste body
Index: src/group/group.h
===================================================================
--- src/group/group.h	(Revision 4352)
+++ src/group/group.h	(Arbeitskopie)
@@ -36,6 +36,7 @@
 #include <beryl_ipcs.h>
 #include <beryl-text.h>
 #include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
 
 #include <math.h>
 #include <limits.h>
@@ -422,6 +423,15 @@
 	GLushort color[4];
 };
 
+typedef struct _GroupWindowHideInfo {
+	Window frameWindow;
+	unsigned long skipState;
+	unsigned long shapeMask;
+	XRectangle *inputRects;
+	int nInputRects;
+	int inputRectOrdering;
+} GroupWindowHideInfo;
+
 /*
  * GroupDisplay structure
  */
@@ -514,6 +524,7 @@
 	GlowQuad *glowQuads;
 
 	GroupWindowState windowState;
+	GroupWindowHideInfo *windowHideInfo;
 
 	// for tab animation
 	Bool ungroup;
@@ -575,6 +586,8 @@
 /*
  * tab.c
  */
+void groupSetWindowVisibility(CompWindow *w, Bool visible);
+void groupClearWindowInputShape(CompWindow *w, GroupWindowHideInfo *hideInfo);
 void groupHandleChanges(CompScreen* s);
 void groupHandleScreenActions(CompScreen *s);
 void groupHandleHoverDetection(GroupSelection *group);
Index: src/group/init.c
===================================================================
--- src/group/init.c	(Revision 4352)
+++ src/group/init.c	(Arbeitskopie)
@@ -272,6 +272,8 @@
 	gw->destination.x = 0;
 	gw->destination.y = 0;
 
+	gw->windowHideInfo = NULL;
+
 	if (w->minimized)
 		gw->windowState = WindowMinimized;
 	else if (w->shaded)
@@ -298,11 +300,8 @@
 {
 	GROUP_WINDOW(w);
 
-	/* TODO: this needs more work; positioning is not correct
-		 at the moment - but it's way better than leaving the 
-		 window offscreen */
-	if (gw->group && gw->group->tabBar && !IS_TOP_TAB(w, gw->group))
-		moveWindowOnscreen(w);
+	if (gw->windowHideInfo)
+		groupSetWindowVisibility(w, TRUE);
 
 	if (gw->glowQuads)
 		free (gw->glowQuads);
Index: src/group/tab.c
===================================================================
--- src/group/tab.c	(Revision 4352)
+++ src/group/tab.c	(Arbeitskopie)
@@ -88,7 +88,119 @@
 	return clip;
 }
 
+
 /*
+ * groupClearWindowInputShape
+ *
+ */
+void
+groupClearWindowInputShape(CompWindow *w, GroupWindowHideInfo *hideInfo)
+{
+	XRectangle *rects;
+	int count, ordering;
+
+	rects = XShapeGetRectangles(w->screen->display->display, 
+			w->id, ShapeInput, &count, &ordering);
+
+	if (count == 0) {
+		XFree(rects);
+		return;
+	}
+
+	/* check if the returned shape exactly matches the window shape -
+	   if that is true, the window currently has no set input shape */
+	if ((count == 1) &&
+		(rects[0].x == -w->serverBorderWidth) &&
+		(rects[0].y == -w->serverBorderWidth) &&
+		(rects[0].width == (w->serverWidth + w->serverBorderWidth)) &&
+		(rects[0].height == (w->serverHeight + w->serverBorderWidth)))
+	{
+		count = 0;
+	}
+
+	if (hideInfo->inputRects)
+		XFree(hideInfo->inputRects);
+
+	hideInfo->inputRects = rects;
+	hideInfo->nInputRects = count;
+	hideInfo->inputRectOrdering = ordering;
+
+	XShapeSelectInput(w->screen->display->display, w->id, NoEventMask);
+			
+	XShapeCombineRectangles(w->screen->display->display, w->id,
+			ShapeInput, 0, 0, NULL, 0, ShapeSet, 0);
+ 
+	XShapeSelectInput(w->screen->display->display, w->id, ShapeNotify);
+}
+
+/*
+ * groupSetWindowVisibility
+ *
+ */
+void
+groupSetWindowVisibility(CompWindow *w, Bool visible)
+{
+	GROUP_WINDOW(w);
+
+	if (!visible && !gw->windowHideInfo) 
+	{
+		gw->windowHideInfo = malloc(sizeof(GroupWindowHideInfo));
+
+		if (!gw->windowHideInfo)
+			return;
+
+		gw->windowHideInfo->inputRects = NULL;
+		gw->windowHideInfo->shapeMask = XShapeInputSelected(
+				w->screen->display->display, w->id);
+		groupClearWindowInputShape(w, gw->windowHideInfo);
+ 		
+ 		if (w->frame) {
+ 			gw->windowHideInfo->frameWindow = w->frame;
+ 			XUnmapWindow(w->screen->display->display, w->frame);
+ 		} else
+			gw->windowHideInfo->frameWindow = None;
+ 
+ 		gw->windowHideInfo->skipState = w->state & 
+ 					(CompWindowStateSkipPagerMask | CompWindowStateSkipTaskbarMask);
+ 		w->state |= (CompWindowStateSkipPagerMask | CompWindowStateSkipTaskbarMask);
+ 		setWindowState(w->screen->display, w->state, w->id);
+ 	} 
+	else if (visible && gw->windowHideInfo) 
+	{
+ 		if (gw->windowHideInfo->nInputRects)
+ 		{
+ 			XShapeCombineRectangles(w->screen->display->display, 
+ 						w->id, ShapeInput, 0, 0, 
+ 						gw->windowHideInfo->inputRects, 
+ 						gw->windowHideInfo->nInputRects,
+ 						ShapeSet, gw->windowHideInfo->inputRectOrdering);
+ 		} else {
+			XShapeCombineMask(w->screen->display->display, w->id,
+					ShapeInput, 0, 0, None, ShapeSet);
+		}
+
+		if (gw->windowHideInfo->inputRects)
+			XFree(gw->windowHideInfo->inputRects);
+
+		XShapeSelectInput(w->screen->display->display, w->id, 
+						gw->windowHideInfo->shapeMask);
+
+		if (gw->windowHideInfo->frameWindow) {
+			if (w->attrib.map_state != IsUnmapped)
+				XMapWindow(w->screen->display->display, w->frame);
+		}
+
+		w->state &= ~(CompWindowStateSkipPagerMask | CompWindowStateSkipTaskbarMask);
+		w->state |= gw->windowHideInfo->skipState;
+		setWindowState(w->screen->display, w->state, w->id);
+
+		free(gw->windowHideInfo);
+		gw->windowHideInfo = NULL;
+	}
+}
+
+
+/*
  * groupTabBarTimeout
  *
  * Description:
@@ -203,8 +315,8 @@
 	oldState = bar->state;
 
 	/* hide tab bars for invisible top windows */
-	if ((topTab->state & (CompWindowStateHiddenMask | 
-			CompWindowStateOffscreenMask)) || topTab->invisible)
+	if ((topTab->state & (CompWindowStateHiddenMask |
+					CompWindowStateOffscreenMask)) || topTab->invisible)
 	{
 		bar->state = PaintOff;
 		groupSwitchTopTabInput(group, TRUE);
@@ -552,7 +664,7 @@
 		if(group->ungroupState == UngroupSingle && group->prevTopTab == NULL)
 		{
 			gs->queued = TRUE;
-			moveWindowOnscreen(topTab);
+			groupSetWindowVisibility(topTab, TRUE);
 			moveWindow(topTab, group->oldTopTabCenterX - WIN_X(topTab) - WIN_WIDTH(topTab) / 2, 
 				group->oldTopTabCenterY - WIN_Y(topTab) - WIN_HEIGHT(topTab) / 2, 
 				TRUE, TRUE); 
@@ -571,7 +683,7 @@
 	}
 
 	gs->queued = TRUE;
-	moveWindowOnscreen(topTab);
+	groupSetWindowVisibility(topTab, TRUE);
 	moveWindow(topTab, group->oldTopTabCenterX - WIN_X(topTab) - WIN_WIDTH(topTab) / 2, 
 		group->oldTopTabCenterY - WIN_Y(topTab) - WIN_HEIGHT(topTab) / 2, 
 		TRUE, TRUE); 
@@ -642,7 +754,7 @@
 		int oldChangeAnimationTime = group->changeAnimationTime;
 		
 		if (group->prevTopTab)
-			moveWindowOffscreen(PREV_TOP_TAB(group));
+			groupSetWindowVisibility(PREV_TOP_TAB(group), FALSE);
 			
 		group->prevTopTab = group->topTab;
 		group->changeState = PaintOff;
@@ -701,7 +813,7 @@
 		if (slot == group->topTab || !(gw->animateState & FINISHED_ANIMATION) || gw->ungroup)
 			continue;
 
-		moveWindowOffscreen(w);
+		groupSetWindowVisibility(w, FALSE);
 	}
 
 	group->changeTab = FALSE;
@@ -800,7 +912,7 @@
 			if (gw->ungroup)
 			{
 				gs->queued = TRUE;
-				moveWindowOnscreen(w);
+				groupSetWindowVisibility(w, TRUE);
 				moveWindow(w, group->oldTopTabCenterX - WIN_X(w) - WIN_WIDTH(w) / 2, 
 					group->oldTopTabCenterY - WIN_Y(w) - WIN_HEIGHT(w) / 2, 
 					TRUE, TRUE);
@@ -1380,6 +1492,11 @@
 	if(!group || group->tabBar)
 		return;
 
+	if (!main->screen->display->shapeExtension) {
+		printf("group plugin: No X shape extension! Tabbing won't work...\n");
+		return;
+	}
+
 	groupInitTabBar(group, main);
 	groupCreateInputPreventionWindow(group);
 	
@@ -1490,7 +1607,7 @@
 		GROUP_WINDOW(cw);
 
 		gs->queued = TRUE;
-		moveWindowOnscreen(cw);
+		groupSetWindowVisibility(cw, TRUE);
 		moveWindow(cw, group->oldTopTabCenterX - WIN_X(cw) - WIN_WIDTH(cw) / 2, 
 			group->oldTopTabCenterY - WIN_Y(cw) - WIN_HEIGHT(cw) / 2, 
 			TRUE, TRUE);
@@ -2429,7 +2546,6 @@
 	} else if (allowUntab) {
 		groupUntabGroup(gw->group);
 	}
-
 	
 	damageScreen(w->screen);
 	
Index: src/group/paint.c
===================================================================
--- src/group/paint.c	(Revision 4352)
+++ src/group/paint.c	(Arbeitskopie)
@@ -1236,7 +1236,6 @@
 		const CompTransform *transform,
 		Region region, unsigned int mask)
 {
-	FragmentAttrib fragment;
 	Bool status;
 	Bool doRotate;
 	GROUP_SCREEN(w->screen);
@@ -1288,8 +1287,6 @@
 		gAttrib.opacity = gAttrib.opacity * opacity / 100; 
 	}            
 	
-	initFragmentAttrib(&fragment, &gAttrib);
-
 	doRotate = gw->group && (gw->group->changeState != PaintOff) &&
 		(IS_TOP_TAB(w, gw->group) || IS_PREV_TOP_TAB(w, gw->group));
 
@@ -1319,6 +1316,9 @@
 		mask |= PAINT_WINDOW_TRANSFORMED_MASK;
 	}
 
+	if (gw->windowHideInfo)
+		mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
+
 	UNWRAP(gs, w->screen, paintWindow);
 	
 	status = (*w->screen->paintWindow) (w, &gAttrib, &wTransform, region, mask);
Index: src/group/group.c
===================================================================
--- src/group/group.c	(Revision 4352)
+++ src/group/group.c	(Arbeitskopie)
@@ -322,7 +322,7 @@
 				CompWindow *lw = group->windows[0];
 
 				gs->queued = TRUE;
-				moveWindowOnscreen(lw);
+				groupSetWindowVisibility(lw, TRUE);
 				moveWindow(lw, group->oldTopTabCenterX - WIN_X(lw) - WIN_WIDTH(lw) / 2, 
 					group->oldTopTabCenterY - WIN_Y(lw) - WIN_HEIGHT(lw) / 2, TRUE, TRUE);
 				syncWindowPosition(lw);
@@ -926,7 +926,7 @@
 					tmpGroup->oldTopTabCenterY = WIN_Y(tw) + WIN_HEIGHT(tw) / 2;
 
 					gs->queued = TRUE;
-					moveWindowOnscreen(gs->draggedSlot->window);
+					groupSetWindowVisibility(gs->draggedSlot->window, TRUE);
 					moveWindow(gs->draggedSlot->window, 
 							gw->group->oldTopTabCenterX - WIN_X(gs->draggedSlot->window) - WIN_WIDTH(gs->draggedSlot->window) / 2, 
 							gw->group->oldTopTabCenterY - WIN_Y(gs->draggedSlot->window) - WIN_HEIGHT(gs->draggedSlot->window) / 2, 
@@ -1090,6 +1090,25 @@
 		groupHandleButtonReleaseEvent(d, event);
 		break;
 
+	case MapNotify:
+		{
+		    CompWindow *cw;
+		    CompWindow *w = findWindowAtDisplay(d, event->xmap.window);
+		    if (!w)
+				break;
+
+		    for (cw = w->screen->windows; cw; cw = cw->next)
+		    {
+				if (w->id == cw->frame)
+				{
+				    GROUP_WINDOW(cw);
+					if (gw->windowHideInfo)
+						XUnmapWindow(cw->screen->display->display, cw->frame);
+				}
+			}
+		}
+		break;
+
 	case UnmapNotify:
 		{
 			CompWindow *w = findWindowAtDisplay(d, event->xunmap.window);
@@ -1160,6 +1179,19 @@
 		break;
 
 	default:
+		if (event->type == d->shapeEvent + ShapeNotify) {
+			XShapeEvent *se = (XShapeEvent*)event;
+			if (se->kind == ShapeInput) {
+				CompWindow *w = findWindowAtDisplay(d, se->window);
+
+				if (w) {
+					GROUP_WINDOW(w);
+
+					if (gw->windowHideInfo)
+						groupClearWindowInputShape(w, gw->windowHideInfo);
+				}
+			}
+		}
 		break;
 	}
 
@@ -1483,21 +1515,23 @@
 	GROUP_WINDOW(w);
 
 	if (gw->group && !gd->ignoreMode && !gs->queued) {
-		int i;
-		for (i = 0; i < gw->group->nWins; i++) {
-			CompWindow *cw = gw->group->windows[i];
-			if (!cw)
-				continue;
+		if (gw->group->tabBar) 
+			groupTabSetVisibility(gw->group, FALSE, 0);
+		else {
+			int i;
+			for (i = 0; i < gw->group->nWins; i++) {
+				CompWindow *cw = gw->group->windows[i];
+				if (!cw)
+					continue;
 			
-			if (cw->id != w->id) 
-				groupEnqueueGrabNotify (cw, x, y, state, mask);
+				if (cw->id != w->id) 
+					groupEnqueueGrabNotify (cw, x, y, state, mask);
+			}
 		}
 
 		gw->group->grabWindow = w->id;
 		gw->group->grabMask = mask;
 
-		if (gw->group->tabBar)
-			groupTabSetVisibility(gw->group, FALSE, 0);
 	}
 
 	UNWRAP(gs, w->screen, windowGrabNotify);
@@ -1512,23 +1546,25 @@
 	GROUP_WINDOW(w);
 
 	if (gw->group && !gd->ignoreMode && !gs->queued) {
-		int i;
+		if (!gw->group->tabBar) {
+			int i;
 
-		groupDequeueMoveNotifies(w->screen);
+			groupDequeueMoveNotifies(w->screen);
 
-		for (i = 0; i < gw->group->nWins; i++) {
-			CompWindow *cw = gw->group->windows[i];
-			if (!cw)
-				continue;
+			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 (cw->id != w->id) {
+					GROUP_WINDOW(cw);
 
-				if (gw->needsPosSync) {
-					syncWindowPosition(cw);
-					gw->needsPosSync = FALSE;
+					if (gw->needsPosSync) {
+						syncWindowPosition(cw);
+						gw->needsPosSync = FALSE;
+					}
+					groupEnqueueUngrabNotify (cw);
 				}
-				groupEnqueueUngrabNotify (cw);
 			}
 		}