static void getTargetRect (CompWindow *cw, GridType where) { GRID_SCREEN (cw->screen); gs->props = gridProps[where]; DEBUG_PRINT ((gridOut, "\nPressed KP_%i\n", where)); /* get current available area */ getWorkareaForOutput (cw->screen, outputDeviceForWindow(cw), &gs->workarea); DEBUG_RECT (workarea); /* Convention: * xxxSlot include decorations (it's the screen area occupied) * xxxRect are undecorated (it's the constrained position of the contents) */ /* slice and dice to get desired slot - including decorations */ gs->desiredSlot.y = gs->workarea.y + gs->props.gravityDown * (gs->workarea.height / gs->props.numCellsY); gs->desiredSlot.height = gs->workarea.height / gs->props.numCellsY; gs->desiredSlot.x = gs->workarea.x + gs->props.gravityRight * (gs->workarea.width / gs->props.numCellsX); gs->desiredSlot.width = gs->workarea.width / gs->props.numCellsX; DEBUG_RECT (desiredSlot); /* Adjust for constraints and decorations */ constrainSize (cw, &gs->desiredSlot, &gs->desiredRect); DEBUG_RECT (gs->desiredRect); }
static void constrainSize (CompWindow *w, XRectangle *slot, XRectangle *rect) { XRectangle workarea; XRectangle r; int cw, ch; getWorkareaForOutput (w->screen, outputDeviceForWindow (w), &workarea); slotToRect (w, slot, &r); if (constrainNewWindowSize (w, r.width, r.height, &cw, &ch)) { /* constrained size may put window offscreen, adjust for that case */ int dx = r.x + cw - workarea.width - workarea.x + w->input.right; int dy = r.y + ch - workarea.height - workarea.y + w->input.bottom; if ( dx > 0 ) r.x -= dx; if ( dy > 0 ) r.y -= dy; r.width = cw; r.height = ch; } *rect = r; }
static void wsnamesDrawText (CompScreen *s) { GLfloat alpha; int ox1, ox2, oy1, oy2; float x, y, border = 10.0f; WSNAMES_SCREEN (s); getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2); x = ox1 + ((ox2 - ox1) / 2) - (ws->textData->width / 2); const BananaValue * option_text_placement = bananaGetOption (bananaIndex, "text_placement", s->screenNum); /* assign y (for the lower corner!) according to the setting */ switch (option_text_placement->i) { case TEXT_PLACEMENT_CENTERED_ON_SCREEN: y = oy1 + ((oy2 - oy1) / 2) + (ws->textData->height / 2); break; case TEXT_PLACEMENT_TOP_OF_SCREEN: case TEXT_PLACEMENET_BOTTOM_OF_SCREEN: { XRectangle workArea; getWorkareaForOutput (s, s->currentOutputDev, &workArea); if (option_text_placement->i == TEXT_PLACEMENT_TOP_OF_SCREEN) y = oy1 + workArea.y + (2 * border) + ws->textData->height; else y = oy1 + workArea.y + workArea.height - (2 * border); } break; default: return; break; } const BananaValue * option_fade_time = bananaGetOption (bananaIndex, "fade_time", s->screenNum); if (ws->timer) alpha = ws->timer / (option_fade_time->f * 1000.0f); else alpha = 1.0f; textDrawText (s, ws->textData, floor (x), floor (y), alpha); }
static void ringDrawWindowTitle (CompScreen *s) { float x, y; int ox1, ox2, oy1, oy2; RING_SCREEN (s); RING_DISPLAY (s->display); getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2); x = ox1 + ((ox2 - ox1) / 2) - ((int)rs->textData->width / 2); /* assign y (for the lower corner!) according to the setting */ switch (ringGetTitleTextPlacement (s)) { case TitleTextPlacementCenteredOnScreen: y = oy1 + ((oy2 - oy1) / 2) + ((int)rs->textData->height / 2); break; case TitleTextPlacementAboveRing: case TitleTextPlacementBelowRing: { XRectangle workArea; getWorkareaForOutput (s, s->currentOutputDev, &workArea); if (ringGetTitleTextPlacement (s) == TitleTextPlacementAboveRing) y = oy1 + workArea.y + (int)rs->textData->height; else y = oy1 + workArea.y + workArea.height; } break; default: return; break; } (rd->textFunc->drawText) (s, rs->textData, floor (x), floor (y), 1.0f); }
static Bool scaleaddonPullWindow(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { CompWindow *w; SCALE_SCREEN(s); ADDON_DISPLAY(d); if (!ss->grabIndex) return FALSE; w = findWindowAtDisplay(d, ad->highlightedWindow); if (w) { int x, y, vx, vy; defaultViewportForWindow(w, &vx, &vy); x = w->attrib.x + (s->x - vx) * s->width; y = w->attrib.y + (s->y - vy) * s->height; if (scaleaddonGetConstrainPullToScreen(s)) { XRectangle workArea; CompWindowExtents extents; getWorkareaForOutput(s, outputDeviceForWindow(w), &workArea); extents.left = x - w->input.left; extents.right = x + w->width + w->input.right; extents.top = y - w->input.top; extents.bottom = y + w->height + w->input.bottom; if (extents.left < workArea.x) x += workArea.x - extents.left; else if (extents.right > workArea.x + workArea.width) x += workArea.x + workArea.width - extents.right; if (extents.top < workArea.y) y += workArea.y - extents.top; else if (extents.bottom > workArea.y + workArea.height) y += workArea.y + workArea.height - extents.bottom; } if (x != w->attrib.x || y != w->attrib.y) { SCALE_WINDOW(w); moveWindowToViewportPosition(w, x, y, TRUE); /* Select this window when ending scale */ (*ss->selectWindow) (w); /* stop scaled window dissapearing */ sw->tx -= (s->x - vx) * s->width; sw->ty -= (s->y - vy) * s->height; if (scaleaddonGetExitAfterPull(s)) { int opt; CompAction *action2; CompOption o[1]; SCALE_DISPLAY(d); opt = SCALE_DISPLAY_OPTION_INITIATE_KEY; action2 = &sd->opt[opt].value.action; o[0].type = CompOptionTypeInt; o[0].name = "root"; o[0].value.i = s->root; if (action2->terminate) (*action2->terminate) (d, action, 0, o, 1); } else { /* provide a simple animation */ addWindowDamage(w); sw->tx -= (sw->slot->x2 - sw->slot->x1) / 20; sw->ty -= (sw->slot->y2 - sw->slot->y1) / 20; sw->scale *= 1.1f; sw->adjust = TRUE; ss->state = SCALE_STATE_OUT; addWindowDamage(w); } return TRUE; } } } return FALSE; }
static Bool gridPlaceWindow (Window xid, GridType where) { CompWindow *w; w = findWindowAtDisplay (xid); if (w) { XRectangle workarea; XRectangle desiredSlot; XRectangle desiredRect; XRectangle currentRect; GridProps props = gridProps[where]; XWindowChanges xwc; /* get current available area */ getWorkareaForOutput (w->screen, outputDeviceForWindow(w), &workarea); /* Convention: * xxxSlot include decorations (it's the screen area occupied) * xxxRect are undecorated (it's the constrained position of the contents) */ /* slice and dice to get desired slot - including decorations */ desiredSlot.y = workarea.y + props.gravityDown * (workarea.height / props.numCellsY); desiredSlot.height = workarea.height / props.numCellsY; desiredSlot.x = workarea.x + props.gravityRight * (workarea.width / props.numCellsX); desiredSlot.width = workarea.width / props.numCellsX; /* Adjust for constraints and decorations */ constrainSize (w, &desiredSlot, &desiredRect); /* Get current rect not including decorations */ currentRect.x = w->serverX; currentRect.y = w->serverY; currentRect.width = w->serverWidth; currentRect.height = w->serverHeight; if (desiredRect.y == currentRect.y && desiredRect.height == currentRect.height) { int slotWidth33 = workarea.width / 3; int slotWidth66 = workarea.width - slotWidth33; if (props.numCellsX == 2) /* keys (1, 4, 7, 3, 6, 9) */ { if (currentRect.width == desiredRect.width && currentRect.x == desiredRect.x) { desiredSlot.width = slotWidth66; desiredSlot.x = workarea.x + props.gravityRight * slotWidth33; } else { /* tricky, have to allow for window constraints when * computing what the 33% and 66% offsets would be */ XRectangle rect33, rect66, slot33, slot66; slot33 = desiredSlot; slot33.x = workarea.x + props.gravityRight * slotWidth66; slot33.width = slotWidth33; constrainSize (w, &slot33, &rect33); slot66 = desiredSlot; slot66.x = workarea.x + props.gravityRight * slotWidth33; slot66.width = slotWidth66; constrainSize (w, &slot66, &rect66); if (currentRect.width == rect66.width && currentRect.x == rect66.x) { desiredSlot.width = slotWidth33; desiredSlot.x = workarea.x + props.gravityRight * slotWidth66; } } } else /* keys (2, 5, 8) */ { if (currentRect.width == desiredRect.width && currentRect.x == desiredRect.x) { desiredSlot.width = slotWidth33; desiredSlot.x = workarea.x + slotWidth33; } } constrainSize (w, &desiredSlot, &desiredRect); } xwc.x = desiredRect.x; xwc.y = desiredRect.y; xwc.width = desiredRect.width; xwc.height = desiredRect.height; if (w->mapNum) sendSyncRequest (w); if (w->state & MAXIMIZE_STATE) { /* maximized state interferes with us, clear it */ maximizeWindow (w, 0); } /* TODO: animate move+resize */ configureXWindow (w, CWX | CWY | CWWidth | CWHeight, &xwc); } return TRUE; }