Public feed #380817

Mine

public text v1 · immutable
Raw Edit
·published 2007-03-04 12:06 UTC
rendered paste body
Index: src/group/group.h
===================================================================
--- src/group/group.h	(Revision 4349)
+++ 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,7 @@
 /*
  * tab.c
  */
+void groupSetWindowVisibility(CompWindow *w, Bool visible);
 void groupHandleChanges(CompScreen* s);
 void groupHandleScreenActions(CompScreen *s);
 void groupHandleHoverDetection(GroupSelection *group);
Index: src/group/init.c
===================================================================
--- src/group/init.c	(Revision 4349)
+++ 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)
@@ -301,8 +303,8 @@
 	/* 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 4349)
+++ src/group/tab.c	(Arbeitskopie)
@@ -113,6 +113,82 @@
 }
 
 /*
+ * 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 = XShapeGetRectangles(
+					w->screen->display->display, w->id, ShapeInput, 
+					&gw->windowHideInfo->nInputRects,
+					&gw->windowHideInfo->inputRectOrdering);
+
+		gw->windowHideInfo->shapeMask = XShapeInputSelected(
+					w->screen->display->display, w->id);
+		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);
+		
+		if (w->frame) {
+			gw->windowHideInfo->frameWindow = w->frame;
+			XUnmapWindow(w->screen->display->display, w->frame);
+			w->frame = 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 > 1)
+		{
+			XShapeCombineRectangles(w->screen->display->display, 
+						w->id, ShapeInput, 0, 0, 
+						gw->windowHideInfo->inputRects, 
+						gw->windowHideInfo->nInputRects,
+						ShapeSet, gw->windowHideInfo->inputRectOrdering);
+		} else {
+			XRectangle rect;
+			rect.x = rect.y = 0;
+			rect.width = w->width;
+			rect.height = w->height;
+
+			XShapeCombineRectangles(w->screen->display->display, w->id,
+						ShapeInput, 0, 0, &rect, 1, ShapeSet, Unsorted);
+		}
+
+		XFree(gw->windowHideInfo->inputRects);
+		XShapeSelectInput(w->screen->display->display, w->id, 
+						gw->windowHideInfo->shapeMask);
+
+		if (gw->windowHideInfo->frameWindow) {
+			w->frame = 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;
+	}
+}
+
+/*
  * groupShowDelayTimeout
  *
  */
@@ -552,7 +628,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 +647,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 +718,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 +777,7 @@
 		if (slot == group->topTab || !(gw->animateState & FINISHED_ANIMATION) || gw->ungroup)
 			continue;
 
-		moveWindowOffscreen(w);
+		groupSetWindowVisibility(w, FALSE);
 	}
 
 	group->changeTab = FALSE;
@@ -800,7 +876,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 +1456,11 @@
 	if(!group || group->tabBar)
 		return;
 
+	if (!main->screen->display->shapeExtension) {
+		printf("group plugin: No X shape extension! Tabbing won't work...\n");
+		return TRUE;
+	}
+
 	groupInitTabBar(group, main);
 	groupCreateInputPreventionWindow(group);
 	
@@ -1490,7 +1571,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 +2510,6 @@
 	} else if (allowUntab) {
 		groupUntabGroup(gw->group);
 	}
-
 	
 	damageScreen(w->screen);
 	
Index: src/group/paint.c
===================================================================
--- src/group/paint.c	(Revision 4349)
+++ 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 4349)
+++ 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, 
@@ -1160,6 +1160,28 @@
 		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 && gw->windowHideInfo->inputRects) {
+						XFree(gw->windowHideInfo->inputRects);
+
+						gw->windowHideInfo->inputRects = XShapeGetRectangles(
+										w->screen->display->display, w->id, ShapeInput, 
+										&gw->windowHideInfo->nInputRects, 
+										&gw->windowHideInfo->inputRectOrdering);
+
+						XShapeCombineRectangles(w->screen->display->display, w->id,
+										ShapeInput, 0, 0, NULL, 0, ShapeSet, 0);
+					}
+				}
+			}
+		}
 		break;
 	}
 
@@ -1472,21 +1494,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);
@@ -1501,23 +1525,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);
 			}
 		}