/* Check if we switched active window, reset the old passive windows * if we did. If we have an active window and switched: reset that too. * If we have a window (w is true), update the active id and * passive list. justMoved is to make sure we recalculate opacity after * moving. We can't reset before moving because if we're using a delay * and the window being moved is not the active but overlapping, it will * be reset, which would conflict with move's opacity change. */ static void opacifyHandleEnter (CompScreen *s, CompWindow *w) { OPACIFY_SCREEN (s); if (otherScreenGrabExist (s, NULL)) { if (!otherScreenGrabExist (s, "move", NULL)) { os->justMoved = TRUE; return; } clearPassive (s); resetOpacity (s, os->active); os->active = 0; return; } if (!w || os->active != w->id || os->justMoved) { os->justMoved = FALSE; clearPassive (s); resetOpacity (s, os->active); os->active = 0; } if (!w) return; if (w->id != os->active && !w->shaded && matchEval (&os->window_match, w)) { int num; os->active = w->id; num = passiveWindows (s, w->region); const BananaValue * option_only_if_block = bananaGetOption (bananaIndex, "only_if_block", s->screenNum); const BananaValue * option_active_opacity = bananaGetOption (bananaIndex, "active_opacity", s->screenNum); if (num || option_only_if_block->b) setOpacity (w, MAX (OPAQUE * option_active_opacity->i / 100, w->paint.opacity)); } }
static Bool shotInitiate (BananaArgument *arg, int nArg) { CompScreen *s; Window xid; BananaValue *root = getArgNamed ("root", arg, nArg); if (root != NULL) xid = root->i; else xid = 0; s = findScreenAtDisplay (xid); if (s) { SHOT_SCREEN (s); if (otherScreenGrabExist (s, "screenshot", NULL)) return FALSE; if (!ss->grabIndex) ss->grabIndex = pushScreenGrab (s, None, "screenshot"); /* start selection screenshot rectangle */ ss->x1 = ss->x2 = pointerX; ss->y1 = ss->y2 = pointerY; ss->grab = TRUE; } return TRUE; }
static Bool moveInitiate(CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption) { CompWindow *w; Window xid; int i, x, y; unsigned int ui; unsigned int mods = 0; MOVE_DISPLAY (d); xid = getIntOptionNamed (option, nOption, "window", 0); w = findWindowAtDisplay (d, xid); if (!w) return FALSE; if (otherScreenGrabExist (w->screen, "move", 0)) return FALSE; MOVE_SCREEN (w->screen); XQueryPointer (d->display, w->screen->root, &xid, &xid, &x, &y, &i, &i, &ui); if (md->w) return FALSE; lastPointerX = x; lastPointerY = y; ms->origState = w->state; if (!ms->grabIndex) ms->grabIndex = pushScreenGrab (w->screen, 0, "move"); if (ms->grabIndex) { md->w = w; (w->screen->windowGrabNotify)(w, x, y, mods, CompWindowGrabMoveMask | CompWindowGrabButtonMask); if (md->moveOpacity != OPAQUE) addWindowDamage (w); } return FALSE; }
static Bool cloneInitiate(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) { int i; CLONE_SCREEN(s); if (cs->grab || otherScreenGrabExist(s, "clone", NULL)) return FALSE; if (!cs->grabIndex) cs->grabIndex = pushScreenGrab(s, None, "clone"); cs->grab = TRUE; cs->x = getIntOptionNamed(option, nOption, "x", 0); cs->y = getIntOptionNamed(option, nOption, "y", 0); cs->src = cs->grabbedOutput = outputDeviceForPoint(s, cs->x, cs->y); /* trace source */ i = 0; while (i < cs->nClone) { if (cs->clone[i].dst == cs->src) { cs->src = cs->clone[i].src; i = 0; } else { i++; } } if (state & CompActionStateInitButton) action->state |= CompActionStateTermButton; } return FALSE; }
static Bool waterInitiate (CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption) { CompScreen *s; unsigned int ui; Window root, child; int xRoot, yRoot, i; for (s = d->screens; s; s = s->next) { WATER_SCREEN (s); if (otherScreenGrabExist (s, "water", NULL)) continue; if (!ws->grabIndex) ws->grabIndex = pushScreenGrab (s, None, "water"); if (XQueryPointer (d->display, s->root, &root, &child, &xRoot, &yRoot, &i, &i, &ui)) { XPoint p; p.x = waterLastPointerX = xRoot; p.y = waterLastPointerY = yRoot; waterVertices (s, GL_POINTS, &p, 1, 0.8f); damageScreen (s); } } if (state & CompActionStateInitButton) action->state |= CompActionStateTermButton; if (state & CompActionStateInitKey) action->state |= CompActionStateTermKey; return FALSE; }
static Bool zoomInitiatePan(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) { int output; ZOOM_SCREEN(s); output = outputDeviceForPoint(s, pointerX, pointerY); if (!(zs->zoomed & (1 << output))) return FALSE; if (otherScreenGrabExist(s, "zoom", NULL)) return FALSE; if (state & CompActionStateInitButton) action->state |= CompActionStateTermButton; if (!zs->panGrabIndex) zs->panGrabIndex = pushScreenGrab(s, zs->panCursor, "zoom-pan"); zs->zoomOutput = output; return TRUE; } return FALSE; }
static void FWHandleIPWMoveInitiate (CompWindow *w) { FREEWINS_WINDOW (w); FREEWINS_SCREEN (w->screen); FREEWINS_DISPLAY (w->screen->display); (*w->screen->activateWindow) (w); fww->grab = grabMove; fws->rotateCursor = XCreateFontCursor (w->screen->display->display, XC_fleur); if(!otherScreenGrabExist(w->screen, "freewins", "move", 0)) if(!fws->grabIndex) { unsigned int mods = 0; mods &= CompNoMask; fws->grabIndex = pushScreenGrab(w->screen, fws->rotateCursor, "move"); (w->screen->windowGrabNotify) (w, w->attrib.x + (w->width / 2), w->attrib.y + (w->height / 2), mods, CompWindowGrabMoveMask | CompWindowGrabButtonMask); } fwd->grabWindow = w; }
/* * Buggy */ static Bool smartputAllTrigger (CompDisplay *d, CompAction *action, CompActionState state, CompOption *option, int nOption) { Window xid; CompWindow *w; CompScreen *s; int grabIndex = 0; xid = getIntOptionNamed (option, nOption, "window", 0); w = findWindowAtDisplay (d, xid); if (w) { s = w->screen; if(otherScreenGrabExist (s, "smartput", 0)) return FALSE; /* * Grab the screen */ grabIndex = pushScreenGrab (s, s->invisibleCursor, "smartput"); if(!grabIndex) return FALSE; CompWindow *window; for (window = s->windows; window; window = window->next) { if(!smartputSameViewport (window,w) ) continue; int width, height; unsigned int mask; XWindowChanges xwc; mask = smartputComputeResize (window, &xwc); if (mask) { if (constrainNewWindowSize (window, xwc.width, xwc.height, &width, &height)) { mask |= CWWidth | CWHeight; xwc.width = width; xwc.height = height; } if (window->mapNum && (mask & (CWWidth | CWHeight))) sendSyncRequest (window); configureXWindow (window, mask, &xwc); } } } if(grabIndex) removeScreenGrab (s,grabIndex, NULL); return TRUE; }
static Bool smartputInitiate (CompWindow *w, CompAction *action, CompActionState state, CompOption *option, int nOption, Bool undo) { CompDisplay *d; if (w) { CompScreen* s = w->screen; SMARTPUT_SCREEN (s); if(otherScreenGrabExist (s, "smartput", 0)) return FALSE; /* * Grab the screen */ if(!sps->grabIndex) sps->grabIndex = pushScreenGrab (s, s->invisibleCursor, "smartput"); if(!sps->grabIndex) return FALSE; int width, height; unsigned int mask; XWindowChanges *xwc; d = s->display; SMARTPUT_WINDOW (w); if(spw->xwc) free(spw->xwc); xwc = malloc(sizeof(XWindowChanges)); if(undo) { if(!(w->id == sps->undoInfo.window) || sps->undoInfo.window == None) return FALSE; mask = smartputUndoResize (s,xwc); } else if(w->id == sps->undoInfo.window && !(sps->undoInfo.window == None) && sps->undoInfo.newX == w->serverX && sps->undoInfo.newY == w->serverY && sps->undoInfo.newWidth == w->serverWidth && sps->undoInfo.newHeight == w->serverHeight && smartputGetUseTriggerkeyForundo (d)) { mask = smartputUndoResize (s,xwc); undo = TRUE; } else { mask = smartputComputeResize (w, xwc); } if (mask) { if (constrainNewWindowSize (w, xwc->width, xwc->height, &width, &height)) { mask |= CWWidth | CWHeight; xwc->width = width; xwc->height = height; } spw->lastX = w->serverX; spw->lastY = w->serverY; spw->targetX = xwc->x; spw->targetY = xwc->y; spw->xwc = xwc; spw->mask = mask; sps->lastWindow = w->id; smartputUpdateUndoInfo (s, w, xwc, undo); spw->animation = TRUE; sps->animation = TRUE; addWindowDamage (w); } } return TRUE; }
static Bool zoomInitiate(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) { int output, x1, y1; float scale; ZOOM_SCREEN(s); if (otherScreenGrabExist(s, "zoom", NULL)) return FALSE; if (!zs->grabIndex) zs->grabIndex = pushScreenGrab(s, None, "zoom"); if (state & CompActionStateInitButton) action->state |= CompActionStateTermButton; /* start selection zoom rectangle */ output = outputDeviceForPoint(s, pointerX, pointerY); if (zs->zoomed & (1 << output)) { ZoomBox box; float oWidth; zoomGetCurrentZoom(s, output, &box); oWidth = s->outputDev[output].width; scale = oWidth / (box.x2 - box.x1); x1 = box.x1; y1 = box.y1; } else { scale = 1.0f; x1 = s->outputDev[output].region.extents.x1; y1 = s->outputDev[output].region.extents.y1; } zs->x1 = zs->x2 = x1 + ((pointerX - s->outputDev[output].region.extents.x1) / scale + 0.5f); zs->y1 = zs->y2 = y1 + ((pointerY - s->outputDev[output].region.extents.y1) / scale + 0.5f); zs->zoomOutput = output; zs->grab = TRUE; damageScreen(s); return TRUE; } return FALSE; }
static Bool ringInitiate (CompScreen *s, CompAction *action, CompActionState state, CompOption *option, int nOption) { CompMatch *match; int count; RING_SCREEN (s); if (otherScreenGrabExist (s, "ring", NULL)) return FALSE; rs->currentMatch = ringGetWindowMatch (s); match = getMatchOptionNamed (option, nOption, "match", NULL); if (match) { matchFini (&rs->match); matchInit (&rs->match); if (matchCopy (&rs->match, match)) { matchUpdate (s->display, &rs->match); rs->currentMatch = &rs->match; } } count = ringCountWindows (s); if (count < 1) return FALSE; if (!rs->grabIndex) { if (ringGetSelectWithMouse (s)) rs->grabIndex = pushScreenGrab (s, s->normalCursor, "ring"); else rs->grabIndex = pushScreenGrab (s, s->invisibleCursor, "ring"); } if (rs->grabIndex) { rs->state = RingStateOut; if (!ringCreateWindowList (s)) return FALSE; rs->selectedWindow = rs->windows[0]; ringRenderWindowTitle (s); rs->rotTarget = 0; rs->moreAdjust = TRUE; damageScreen (s); switchActivateEvent (s, TRUE); } return TRUE; }
/* * groupHandleButtonPressEvent * */ static void groupHandleButtonPressEvent (CompScreen *s, XEvent *event) { GroupSelection *group; int xRoot, yRoot, button; GROUP_SCREEN (s); xRoot = event->xbutton.x_root; yRoot = event->xbutton.y_root; button = event->xbutton.button; for (group = gs->groups; group; group = group->next) { if (group->inputPrevention != event->xbutton.window) continue; if (!group->tabBar) continue; switch (button) { case Button1: { GroupTabBarSlot *slot; for (slot = group->tabBar->slots; slot; slot = slot->next) { if (XPointInRegion (slot->region, xRoot, yRoot)) { gs->draggedSlot = slot; /* The slot isn't dragged yet */ gs->dragged = FALSE; gs->prevX = xRoot; gs->prevY = yRoot; if (!otherScreenGrabExist (s, "group", "group-drag", NULL)) groupGrabScreen (s, ScreenGrabTabDrag); } } } break; case Button4: case Button5: { CompWindow *topTab = NULL; GroupWindow *gw; if (group->nextTopTab) topTab = NEXT_TOP_TAB (group); else if (group->topTab) { /* If there are no tabbing animations, topTab is never NULL. */ topTab = TOP_TAB (group); } if (!topTab) return; gw = GET_GROUP_WINDOW (topTab, gs); if (button == Button4) { if (gw->slot->prev) groupChangeTab (gw->slot->prev, RotateLeft); else groupChangeTab (gw->group->tabBar->revSlots, RotateLeft); } else { if (gw->slot->next) groupChangeTab (gw->slot->next, RotateRight); else groupChangeTab (gw->group->tabBar->slots, RotateRight); } break; } } break; } }
/* X Event Handler */ void FWHandleEvent(CompDisplay *d, XEvent *ev){ float dx, dy; CompWindow *oldPrev, *oldNext, *w; FREEWINS_DISPLAY(d); /* Check our modifiers first */ if (ev->type == d->xkbEvent) { XkbAnyEvent *xkbEvent = (XkbAnyEvent *) ev; if (xkbEvent->xkb_type == XkbStateNotify) { XkbStateNotifyEvent *stateEvent = (XkbStateNotifyEvent *) ev; unsigned int snapMods = 0xffffffff; unsigned int invertMods = 0xffffffff; if (fwd->snapMask) snapMods = fwd->snapMask; if ((stateEvent->mods & snapMods) == snapMods) fwd->snap = TRUE; else fwd->snap = FALSE; if (fwd->invertMask) invertMods = fwd->invertMask; if ((stateEvent->mods & invertMods) == invertMods) fwd->invert = TRUE; else fwd->invert = FALSE; } } switch(ev->type){ case EnterNotify: { CompWindow *btnW; btnW = findWindowAtDisplay (d, ev->xbutton.subwindow); /* It wasn't the subwindow, try the window */ if (!btnW) btnW = findWindowAtDisplay (d, ev->xbutton.window); /* We have established the CompWindow we clicked * on. Get the real window */ if (btnW) { if (FWCanShape (btnW) && !fwd->grabWindow && !otherScreenGrabExist(btnW->screen, 0)) fwd->hoverWindow = btnW; btnW = FWGetRealWindow (btnW); } if (btnW) { if (FWCanShape (btnW) && !fwd->grabWindow && !otherScreenGrabExist(btnW->screen, 0)) fwd->hoverWindow = btnW; FWHandleEnterNotify (btnW, ev); } } break; case LeaveNotify: { CompWindow *btnW; btnW = findWindowAtDisplay (d, ev->xbutton.subwindow); /* It wasn't the subwindow, try the window */ if (!btnW) btnW = findWindowAtDisplay (d, ev->xbutton.window); /* We have established the CompWindow we clicked * on. Get the real window */ if (btnW) btnW = FWGetRealWindow (btnW); if (btnW) FWHandleLeaveNotify (btnW, ev); } break; case MotionNotify: if(fwd->grabWindow) { FREEWINS_WINDOW(fwd->grabWindow); dx = ((float)(pointerX - lastPointerX) / fwd->grabWindow->screen->width) * \ freewinsGetMouseSensitivity (fwd->grabWindow->screen); dy = ((float)(pointerY - lastPointerY) / fwd->grabWindow->screen->height) * \ freewinsGetMouseSensitivity (fwd->grabWindow->screen); if (matchEval (freewinsGetShapeWindowTypes (fwd->grabWindow->screen), fwd->grabWindow)) { if (fww->grab == grabMove || fww->grab == grabResize) { FREEWINS_SCREEN (fwd->grabWindow->screen); FWWindowInputInfo *info; CompWindow *w = fwd->grabWindow; for (info = fws->transformedWindows; info; info = info->next) { if (fwd->grabWindow->id == info->ipw) /* The window we just grabbed was actually * an IPW, get the real window instead */ w = FWGetRealWindow (fwd->grabWindow); } switch (fww->grab) { case grabMove: FWHandleIPWMoveMotionEvent (w, pointerX, pointerY); break; case grabResize: FWHandleIPWResizeMotionEvent (w, pointerX, pointerY); break; default: break; } } } if (fww->grab == grabRotate) { FWHandleRotateMotionEvent(fwd->grabWindow, dx, dy, ev->xmotion.x, ev->xmotion.y); } if (fww->grab == grabScale) { FWHandleScaleMotionEvent(fwd->grabWindow, dx * 3, dy * 3, ev->xmotion.x, ev->xmotion.y); } if(dx != 0.0 || dy != 0.0) FWDamageArea (fwd->grabWindow); } break; /* Button Press and Release */ case ButtonPress: { CompWindow *btnW; btnW = findWindowAtDisplay (d, ev->xbutton.subwindow); /* It wasn't the subwindow, try the window */ if (!btnW) btnW = findWindowAtDisplay (d, ev->xbutton.window); /* We have established the CompWindow we clicked * on. Get the real window * FIXME: Free btnW and use another CompWindow * such as realW */ if (btnW) btnW = FWGetRealWindow (btnW); if (btnW) { if (matchEval (freewinsGetShapeWindowTypes (btnW->screen), btnW)) switch (ev->xbutton.button) { case Button1: FWHandleIPWMoveInitiate (btnW); break; case Button3: FWHandleIPWResizeInitiate (btnW); break; default: break; } } fwd->click_root_x = ev->xbutton.x_root; fwd->click_root_y = ev->xbutton.y_root; } break; case ButtonRelease: { if (fwd->grabWindow) { FREEWINS_WINDOW (fwd->grabWindow); if (matchEval (freewinsGetShapeWindowTypes (fwd->grabWindow->screen), fwd->grabWindow)) if (fww->grab == grabMove || fww->grab == grabResize) { FWHandleButtonReleaseEvent (fwd->grabWindow); fwd->grabWindow = 0; } } } break; case ConfigureNotify: w = findWindowAtDisplay (d, ev->xconfigure.window); if (w) { oldPrev = w->prev; oldNext = w->next; FREEWINS_WINDOW (w); fww->winH = WIN_REAL_H (w); fww->winW = WIN_REAL_W (w); } break; case ClientMessage: if (ev->xclient.message_type == d->desktopViewportAtom) { /* Viewport change occurred, or something like that - adjust the IPW's */ CompScreen *s; CompWindow *adjW, *actualW; for (s = d->screens; s; s = s->next) for (adjW = s->windows; adjW; adjW = adjW->next) { int vX = 0, vY = 0, dX, dY; actualW = FWGetRealWindow (adjW); if (!actualW) actualW = adjW; if (actualW) { CompWindow *ipw; FREEWINS_WINDOW (actualW); if (!fww->input || fww->input->ipw) break; ipw = findWindowAtDisplay (d, fww->input->ipw); if (ipw) { dX = s->x - vX; dY = s->y - vY; defaultViewportForWindow (actualW, &vX, &vY); moveWindowToViewportPosition (ipw, ipw->attrib.x - dX * s->width, ipw->attrib.y - dY * s->height, FALSE); } } } } break; default: if (ev->type == d->shapeEvent + ShapeNotify) { XShapeEvent *se = (XShapeEvent *) ev; if (se->kind == ShapeInput) { CompWindow *w; w = findWindowAtDisplay (d, se->window); if (w) { FREEWINS_WINDOW (w); if (FWCanShape (w) && (fww->transform.scaleX != 1.0f || fww->transform.scaleY != 1.0f)) { // Reset the window back to normal fww->transform.scaleX = 1.0f; fww->transform.scaleY = 1.0f; fww->transform.angX = 0.0f; fww->transform.angY = 0.0f; fww->transform.angZ = 0.0f; /*FWShapeInput (w); - Disabled due to problems it causes*/ } } } } } UNWRAP(fwd, d, handleEvent); (*d->handleEvent)(d, ev); WRAP(fwd, d, handleEvent, FWHandleEvent); /* Now we can find out if a restacking occurred while we were handing events */ switch (ev->type) { case ConfigureNotify: if (w) /* already assigned above */ { if (w->prev != oldPrev || w->next != oldNext) { /* restacking occured, ensure ipw stacking */ FWAdjustIPWStacking (w->screen); FWAdjustIPW (w); } } break; } }