예제 #1
0
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;
}
예제 #2
0
/* 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;
    }
}