rendered paste bodyIndex: 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);
}
}