static void minDonePaintScreen (CompScreen *s) { MIN_SCREEN (s); if (ms->moreAdjust) { CompWindow *w; int h; for (w = s->windows; w; w = w->next) { MIN_WINDOW (w); if (mw->adjust) { addWindowDamage (w); } else if (mw->region) { h = w->attrib.height + w->attrib.border_width * 2; if (mw->shade && mw->shade < h) addWindowDamage (w); } } } UNWRAP (ms, s, donePaintScreen); (*s->donePaintScreen) (s); WRAP (ms, s, donePaintScreen, minDonePaintScreen); }
static void minSetShade (CompWindow *w, int shade) { REGION rect; int h = w->attrib.height + w->attrib.border_width * 2; MIN_WINDOW (w); EMPTY_REGION (w->region); rect.rects = &rect.extents; rect.numRects = rect.size = 1; w->height = shade; rect.extents.x1 = 0; rect.extents.y1 = h - shade; rect.extents.x2 = w->width; rect.extents.y2 = h; XIntersectRegion (mw->region, &rect, w->region); XOffsetRegion (w->region, w->attrib.x, w->attrib.y - (h - shade)); w->matrix = w->texture->matrix; w->matrix.x0 -= (w->attrib.x * w->matrix.xx); w->matrix.y0 -= ((w->attrib.y - (h - shade)) * w->matrix.yy); (*w->screen->windowResizeNotify) (w, 0, 0, 0, 0); }
static Bool minPaintWindow (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { CompScreen *s = w->screen; Bool status; MIN_SCREEN (s); MIN_WINDOW (w); if (mw->adjust) { FragmentAttrib fragment; CompTransform wTransform = *transform; if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) return FALSE; UNWRAP (ms, s, paintWindow); status = (*s->paintWindow) (w, attrib, transform, region, mask | PAINT_WINDOW_NO_CORE_INSTANCE_MASK); WRAP (ms, s, paintWindow, minPaintWindow); initFragmentAttrib (&fragment, &w->lastPaint); if (w->alpha || fragment.opacity != OPAQUE) mask |= PAINT_WINDOW_TRANSLUCENT_MASK; matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f); matrixScale (&wTransform, mw->xScale, mw->yScale, 1.0f); matrixTranslate (&wTransform, mw->tx / mw->xScale - w->attrib.x, mw->ty / mw->yScale - w->attrib.y, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*s->drawWindow) (w, &wTransform, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); glPopMatrix (); } else { /* no core instance from windows that have been animated */ if (mw->state == IconicState) mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK; UNWRAP (ms, s, paintWindow); status = (*s->paintWindow) (w, attrib, transform, region, mask); WRAP (ms, s, paintWindow, minPaintWindow); } return status; }
static void minFiniWindow(CompPlugin * p, CompWindow * w) { MIN_WINDOW(w); mw->ignoreDamage = TRUE; while (mw->unmapCnt--) unmapWindow(w); mw->ignoreDamage = FALSE; if (mw->region) XDestroyRegion(mw->region); free(mw); }
static Bool minFocusWindow(CompWindow * w) { Bool status; MIN_SCREEN(w->screen); MIN_WINDOW(w); if (mw->unmapCnt) return FALSE; UNWRAP(ms, w->screen, focusWindow); status = (*w->screen->focusWindow) (w); WRAP(ms, w->screen, focusWindow, minFocusWindow); return status; }
static Bool minDamageWindowRect (CompWindow *w, Bool initial, BoxPtr rect) { Bool status = FALSE; MIN_SCREEN (w->screen); MIN_WINDOW (w); if (mw->ignoreDamage) return TRUE; if (initial) { if (mw->state == IconicState) { mw->state = NormalState; if (!w->invisible && w->iconGeometrySet && matchEval (&ms->match, w)) { if (!mw->adjust) { mw->adjust = TRUE; ms->moreAdjust = TRUE; mw->tx = w->iconGeometry.x - w->serverX; mw->ty = w->iconGeometry.y - w->serverY; mw->xScale = (float) w->iconGeometry.width / w->width; mw->yScale = (float) w->iconGeometry.height / w->height; addWindowDamage (w); } } } else if (mw->region && mw->shade < w->height) { if (ms->shadeStep && !w->invisible) { XSubtractRegion (w->region, &emptyRegion, mw->region); XOffsetRegion (mw->region, -w->attrib.x, -w->attrib.y); /* bind pixmap here so we have something to unshade with */ if (!w->texture->pixmap && !w->bindFailed) bindWindow (w); ms->moreAdjust = TRUE; } else { mw->shade = MAXSHORT; } } mw->newState = NormalState; } else if (mw->adjust) { damageTransformedWindowRect (w, mw->xScale, mw->yScale, mw->tx, mw->ty, rect); status = TRUE; } UNWRAP (ms, w->screen, damageWindowRect); status |= (*w->screen->damageWindowRect) (w, initial, rect); WRAP (ms, w->screen, damageWindowRect, minDamageWindowRect); return status; }
static void minHandleEvent (XEvent *event) { CompWindow *w; MIN_DISPLAY (&display); switch (event->type) { case MapNotify: w = findWindowAtDisplay (event->xmap.window); if (w) { MIN_WINDOW (w); if (mw->adjust) mw->state = mw->newState; if (mw->region) w->height = 0; mw->ignoreDamage = TRUE; while (mw->unmapCnt) { unmapWindow (w); mw->unmapCnt--; } mw->ignoreDamage = FALSE; } break; case UnmapNotify: w = findWindowAtDisplay (event->xunmap.window); if (w) { MIN_SCREEN (w->screen); if (w->pendingUnmaps && onCurrentDesktop (w)) /* Normal -> Iconic */ { MIN_WINDOW (w); if (w->shaded) { if (!mw->region) mw->region = XCreateRegion (); if (mw->region && ms->shadeStep) { XSubtractRegion (w->region, &emptyRegion, mw->region); XOffsetRegion (mw->region, -w->attrib.x, w->attrib.height + w->attrib.border_width * 2 - w->height - w->attrib.y); mw->shade = w->height; mw->adjust = FALSE; ms->moreAdjust = TRUE; mw->unmapCnt++; w->unmapRefCnt++; addWindowDamage (w); } } else if (!w->invisible && matchEval (&ms->match, w)) { if (w->iconGeometrySet) { mw->newState = IconicState; mw->xScale = w->paint.xScale; mw->yScale = w->paint.yScale; mw->tx = w->attrib.x - w->serverX; mw->ty = w->attrib.y - w->serverY; if (mw->region) { XDestroyRegion (mw->region); mw->region = NULL; } mw->shade = MAXSHORT; mw->adjust = TRUE; ms->moreAdjust = TRUE; mw->unmapCnt++; w->unmapRefCnt++; addWindowDamage (w); } } } else /* X -> Withdrawn */ { MIN_WINDOW (w); if (mw->adjust) { mw->adjust = FALSE; mw->xScale = mw->yScale = 1.0f; mw->tx = mw->ty = 0.0f; mw->xVelocity = mw->yVelocity = 0.0f; mw->xScaleVelocity = mw->yScaleVelocity = 1.0f; mw->shade = MAXSHORT; if (mw->region) { XDestroyRegion (mw->region); mw->region = NULL; } } mw->state = NormalState; } } default: break; } UNWRAP (md, &display, handleEvent); (*display.handleEvent) (event); WRAP (md, &display, handleEvent, minHandleEvent); switch (event->type) { case MapRequest: w = findWindowAtDisplay (event->xmaprequest.window); if (w && w->hints && w->hints->initial_state == IconicState) { MIN_WINDOW (w); mw->newState = mw->state = IconicState; } break; default: break; } }
static void minPreparePaintScreen (CompScreen *s, int msSinceLastPaint) { MIN_SCREEN (s); if (ms->moreAdjust) { CompWindow *w; int steps, h; float amount, chunk; const BananaValue * option_speed = bananaGetOption (bananaIndex, "speed", s->screenNum); amount = msSinceLastPaint * 0.05f * option_speed->f; const BananaValue * option_timestep = bananaGetOption (bananaIndex, "timestep", s->screenNum); steps = amount / (0.5f * option_timestep->f); if (!steps) steps = 1; chunk = amount / (float) steps; while (steps--) { ms->moreAdjust = 0; for (w = s->windows; w; w = w->next) { MIN_WINDOW (w); if (mw->adjust) { mw->adjust = adjustMinVelocity (w); ms->moreAdjust |= mw->adjust; mw->tx += mw->xVelocity * chunk; mw->ty += mw->yVelocity * chunk; mw->xScale += mw->xScaleVelocity * chunk; mw->yScale += mw->yScaleVelocity * chunk; if (!mw->adjust) { mw->state = mw->newState; mw->ignoreDamage = TRUE; while (mw->unmapCnt) { unmapWindow (w); mw->unmapCnt--; } mw->ignoreDamage = FALSE; } } else if (mw->region && w->damaged) { if (w->shaded) { if (mw->shade > 0) { mw->shade -= (chunk * ms->shadeStep) + 1; if (mw->shade > 0) { ms->moreAdjust = TRUE; } else { mw->shade = 0; mw->ignoreDamage = TRUE; while (mw->unmapCnt) { unmapWindow (w); mw->unmapCnt--; } mw->ignoreDamage = FALSE; } } } else { h = w->attrib.height + w->attrib.border_width * 2; if (mw->shade < h) { mw->shade += (chunk * ms->shadeStep) + 1; if (mw->shade < h) { ms->moreAdjust = TRUE; } else { mw->shade = MAXSHORT; minSetShade (w, h); XDestroyRegion (mw->region); mw->region = NULL; addWindowDamage (w); } } } } } if (!ms->moreAdjust) break; } if (ms->moreAdjust) { for (w = s->windows; w; w = w->next) { MIN_WINDOW (w); if (mw->adjust) { addWindowDamage (w); } else if (mw->region && w->damaged) { h = w->attrib.height + w->attrib.border_width * 2; if (mw->shade && mw->shade < h) { minSetShade (w, mw->shade); addWindowDamage (w); } } } } } UNWRAP (ms, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP (ms, s, preparePaintScreen, minPreparePaintScreen); }
static int adjustMinVelocity (CompWindow *w) { float dx, dy, dxs, dys, adjust, amount; float x1, y1, xScale, yScale; MIN_WINDOW (w); if (mw->newState == IconicState) { x1 = w->iconGeometry.x; y1 = w->iconGeometry.y; xScale = (float) w->iconGeometry.width / w->width; yScale = (float) w->iconGeometry.height / w->height; } else { x1 = w->serverX; y1 = w->serverY; xScale = yScale = 1.0f; } dx = x1 - (w->attrib.x + mw->tx); adjust = dx * 0.15f; amount = fabs (dx) * 1.5f; if (amount < 0.5f) amount = 0.5f; else if (amount > 5.0f) amount = 5.0f; mw->xVelocity = (amount * mw->xVelocity + adjust) / (amount + 1.0f); dy = y1 - (w->attrib.y + mw->ty); adjust = dy * 0.15f; amount = fabs (dy) * 1.5f; if (amount < 0.5f) amount = 0.5f; else if (amount > 5.0f) amount = 5.0f; mw->yVelocity = (amount * mw->yVelocity + adjust) / (amount + 1.0f); dxs = xScale - mw->xScale; adjust = dxs * 0.15f; amount = fabs (dxs) * 10.0f; if (amount < 0.01f) amount = 0.01f; else if (amount > 0.15f) amount = 0.15f; mw->xScaleVelocity = (amount * mw->xScaleVelocity + adjust) / (amount + 1.0f); dys = yScale - mw->yScale; adjust = dys * 0.15f; amount = fabs (dys) * 10.0f; if (amount < 0.01f) amount = 0.01f; else if (amount > 0.15f) amount = 0.15f; mw->yScaleVelocity = (amount * mw->yScaleVelocity + adjust) / (amount + 1.0f); if (fabs (dx) < 0.1f && fabs (mw->xVelocity) < 0.2f && fabs (dy) < 0.1f && fabs (mw->yVelocity) < 0.2f && fabs (dxs) < 0.001f && fabs (mw->xScaleVelocity) < 0.002f && fabs (dys) < 0.001f && fabs (mw->yScaleVelocity) < 0.002f) { mw->xVelocity = mw->yVelocity = mw->xScaleVelocity = mw->yScaleVelocity = 0.0f; mw->tx = x1 - w->attrib.x; mw->ty = y1 - w->attrib.y; mw->xScale = xScale; mw->yScale = yScale; return 0; } return 1; }