Exemplo n.º 1
0
/*************************************<->*************************************
 *
 *  DoPlacement (pcd)
 *
 *
 *  Description:
 *  -----------
 *  Gets window configuration from the user via pointer/keyboard interaction
 *
 *
 *  Inputs:
 *  ------
 *  pcd		- pointer to client data
 *
 * 
 *  Outputs:
 *  -------
 *  pcd		- clientX, clientY, clientWidth, and clientHeight members
 *		  could be changed
 *
 *  Comments:
 *  --------
 *  We try to be careful only to remove events that we need from the 
 *  event queue while we're in our own event processing loop.
 * 
 *************************************<->***********************************/
void DoPlacement (ClientData *pcd)
{
    XEvent event;

    /*
     * Initialization
     */
    SetupPlacement (pcd);

    /*
     * Process events
     */
    placementDone = FALSE;
    while (!placementDone)
    {
	GetConfigEvent (DISPLAY, ACTIVE_ROOT, GRAB_MASK,
		placePointerX, placePointerY, placeX, placeY, 
		placeWidth, placeHeight, &event);

	switch (event.type) {
	    case KeyPress:
		HandlePlacementKeyEvent(pcd, (XKeyEvent *)&event);
		break;

	    case ButtonPress:
		HandlePlacementButtonEvent((XButtonEvent *)&event);
		break;

	    case ButtonRelease:
		HandlePlacementButtonEvent((XButtonEvent *)&event);
		break;

	    case MotionNotify:
		HandlePlacementMotionEvent(pcd, (XMotionEvent *)&event);
		break;

	}
    }
    
    /* copy back the configuration information */
    pcd->clientX = placeX + placeOffsetX;
    pcd->clientY = placeY + placeOffsetY; 
    pcd->clientWidth = placeWidth - 2*placeOffsetX;
    pcd->clientHeight = placeHeight - placeOffsetX - placeOffsetY;

    /* clean up */
    MoveOutline (0,0,0,0);
    HideFeedbackWindow(pcd->pSD);

} /* END OF FUNCTION DoPlacement  */
Exemplo n.º 2
0
void HandlePlacementMotionEvent (ClientData *pcd, XMotionEvent *pev)
{
    int diffx, diffy;

    /*
     * If in pre-resize mode, check for motion crossing threshhold before 
     * switching modes
     */
    if (wmGD.preMove) {
	diffx = pev->x_root - wmGD.preMoveX;
	diffy = pev->y_root - wmGD.preMoveY;
	if ((ABS(diffx) > wmGD.moveThreshold) ||
	    (ABS(diffy) > wmGD.moveThreshold))
	{
	    StartInteractiveSizing(pcd, pev->time);
	}
	return; 
    }

    if (placeResize) {
	/*
	 * Track lower right corner
	 */
	if (pev->x_root > placeX)
	    placeWidth = pev->x_root - placeX + 1;
	if (pev->y_root > placeY)
	    placeHeight = pev->y_root - placeY + 1;
    }
    else {
	/*
	 * track window position
	 */
	placeX = pev->x_root;
	placeY = pev->y_root;
    }

    placePointerX = pev->x_root;
    placePointerY = pev->y_root;

    FixFrameValues (pcd, &placeX, &placeY, &placeWidth, &placeHeight,
		    placeResize);

    MoveOutline (placeX, placeY, placeWidth, placeHeight);

    if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
    {
	DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight, 
	            0, placeResize);
    }
} /* END OF FUNCTION HandlePlacementMotionEvent */
Exemplo n.º 3
0
/*************************************<->*************************************
 *
 *  SetupPlacement (pcd)
 *
 *
 *  Description:
 *  -----------
 *  Perform the initialization for interactive placement
 *
 *
 *  Inputs:
 *  ------
 *  pcd		- pointer to client data
 * 
 *  Outputs:
 *  -------
 *
 *
 *  Comments:
 *  --------
 * o sets up global data and puts initial display on the screen
 * 
 *************************************<->***********************************/
void SetupPlacement (ClientData *pcd)
{
    int cX, cY, junk;
    Window junk_win;

    /*
     * Restore the state of the last "depressed" frame gadget
     */

    if (wmGD.gadgetClient && wmGD.gadgetDepressed)
    {
	PopGadgetOut(wmGD.gadgetClient, wmGD.gadgetDepressed);

    }
	
    /* get offset of frame origin from window origin */
    placeOffsetX = pcd->clientOffset.x;
    placeOffsetY = pcd->clientOffset.y;

    XQueryPointer (DISPLAY, ACTIVE_ROOT, 
		   &junk_win, &junk_win,
		   &cX, &cY, &junk, &junk, (unsigned int *)&junk);

    /* convert to frame coordinates */
    placePointerX = placeX = cX;
    placePointerY = placeY = cY;
    placeWidth = pcd->clientWidth;
    placeHeight = pcd->clientHeight;
    ClientToFrame (pcd, &cX, &cY, &placeWidth, &placeHeight);

    /* in "position" mode to start with */
    placeResize = FALSE;
    wmGD.preMove = FALSE;

    /* normal window being dealt with, not icon */
    wmGD.movingIcon = FALSE;

    if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
    {
        DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight, 
		    (FB_SIZE | FB_POSITION), placeResize);
    }

    /* set up initial visual feedback */
    MoveOutline (placeX, placeY, placeWidth, placeHeight);

} /* END OF FUNCTION SetupPlacement  */
Exemplo n.º 4
0
void HandlePlacementKeyEvent (ClientData *pcd, XKeyEvent *pev)
{
    XEvent KeyEvent;
    KeySym keysym;
    Boolean control, valid;
    int big_inc;
    int tmpX = 0;
    int tmpY = 0;
    int warpX, warpY, newX, newY;
    int keyPlaceX = placeX;
    int keyPlaceY = placeY;
    unsigned int keyPlaceWidth = placeWidth;
    unsigned int keyPlaceHeight = placeHeight;

    /* filter out repeating keys */
    placeKeyMultiplier = 1;
    if (pev->type == KeyPress)
    {
	while (placeKeyMultiplier <= 10 && 
		  XCheckIfEvent (DISPLAY, &KeyEvent, IsRepeatedKeyEvent, 
		  (char *) pev))
	{
	      placeKeyMultiplier++;
	}
    }

    /* convert event data to useful key data */
#ifdef FIX_1611
    keysym = WmKeycodeToKeysym(DISPLAY, pev->keycode);
#else 
    keysym = XKeycodeToKeysym (DISPLAY, pev->keycode, 0);
#endif    
    control = (pev->state & ControlMask) != 0;
    big_inc = DisplayWidth(DISPLAY, ACTIVE_PSD->screen) / 20;

    /* interpret key data */
    valid = FALSE;
    switch (keysym) 
    {
	case XK_Left:
	    tmpX = (control) ? (-big_inc) : -1;
	    valid = TRUE;
	    break;

	case XK_Up:
	    tmpY = (control) ? (-big_inc) : -1;
	    valid = TRUE;
	    break;

	case XK_Right:
	    tmpX = (control) ? (big_inc) : 1;
	    valid = TRUE;
	    break;

	case XK_Down:
	    tmpY = (control) ? (big_inc) : 1;
	    valid = TRUE;
	    break;

	case XK_space:
	    StartInteractiveSizing(pcd, pev->time);
	    break;

	case XK_Return:
	    placementDone = TRUE;	/* global "done" flag */
	    break;

	default:
	    break;
    }


    /* if a valid key was pressed, then react to it */
    if (valid) {
	tmpX *= placeKeyMultiplier;
	tmpY *= placeKeyMultiplier;

	if (placeResize)
	{
	    keyPlaceWidth += tmpX;		/* change size of outline */
	    keyPlaceHeight += tmpY;

	    FixFrameValues(pcd, &keyPlaceX, &keyPlaceY, &keyPlaceWidth, 
		           &keyPlaceHeight, placeResize);

	    warpX = keyPlaceX+keyPlaceWidth-1;
	    warpY = keyPlaceY+keyPlaceHeight-1;

	    SetPointerPosition (warpX, warpY, &newX, &newY);

	    if ((warpX == newX) && (warpY == newY))
	    {
		placeWidth = keyPlaceWidth;
		placeHeight = keyPlaceHeight;
	    }
	    else 
	    {
		placeWidth = newX - keyPlaceX + 1;
		placeHeight = newY - keyPlaceY + 1;
	    }
	}
	else 
	{
	    keyPlaceX += tmpX;		/* change position of outline */
	    keyPlaceY += tmpY;

	    FixFrameValues(pcd, &keyPlaceX, &keyPlaceY, &keyPlaceWidth, 
		           &keyPlaceHeight, placeResize);

	    warpX = keyPlaceX;
	    warpY = keyPlaceY;

	    SetPointerPosition (warpX, warpY, &newX, &newY);

	    placeX = newX;
	    placeY = newY;
	}
	placePointerX = newX;
	placePointerY = newY;
    }
    FixFrameValues (pcd, &placeX, &placeY, &placeWidth, &placeHeight,
		    placeResize);

    MoveOutline (placeX, placeY, placeWidth, placeHeight);

    if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
    {
	DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight, 
	            0, placeResize);
    }
} /* END OF FUNCTION HandlePlacementKeyEvent */
Exemplo n.º 5
0
Arquivo: move.c Projeto: tonnerre/fvwm
/****************************************************************************
 *
 * Move the rubberband around, return with the new window location
 *
 ****************************************************************************/
void moveLoop(FvwmWindow *tmp_win, int XOffset, int YOffset, int Width,
	      int Height, int *FinalX, int *FinalY,Bool opaque_move,
	      Bool AddWindow)
{
  Bool finished = False;
  Bool done;
  int xl,yt,delta_x,delta_y;
#ifndef NO_PAGER
  unsigned int pagerwidth,pagerheight;
  int ww,wh;
  int wx,wy;
  int MaxH,MaxW;
  int last_x = -10000, last_y = -10000;

#endif
  XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,&xl, &yt,
		&JunkX, &JunkY, &JunkMask);
  xl += XOffset;
  yt += YOffset;

  if(((!opaque_move)&&(!(Scr.flags & MWMMenus)))||(AddWindow))
    MoveOutline(Scr.Root, xl, yt, Width,Height);

  DisplayPosition(tmp_win,xl+Scr.Vx,yt+Scr.Vy,True);

  while (!finished)
    {
      /* block until there is an interesting event */
      XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask |
		 PointerMotionMask | ButtonMotionMask | ExposureMask, &Event);
      StashEventTime(&Event);      

      /* discard any extra motion events before a logical release */
      if (Event.type == MotionNotify) 
	{
	  while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask |
				ButtonPressMask |ButtonRelease, &Event))
	    {
	      StashEventTime(&Event);
	      if(Event.type == ButtonRelease) break;
	    }
	}

      done = FALSE;
      /* Handle a limited number of key press events to allow mouseless
       * operation */
      if(Event.type == KeyPress)
	Keyboard_shortcuts(&Event,ButtonRelease);
      switch(Event.type)
	{
	case KeyPress:
	  done = TRUE;
	  break;
	case ButtonPress:
	  XAllowEvents(dpy,ReplayPointer,CurrentTime);
	  if(((Event.xbutton.button == 2)&&(!(Scr.flags & MWMMenus)))||
	     ((Event.xbutton.button == 1)&&(Scr.flags & MWMMenus)&&
	      (Event.xbutton.state & ShiftMask)))
	    {
	      NeedToResizeToo = True;
	      /* Fallthrough to button-release */
	    }
	  else
	    {
	      done = 1;
	      break;
	    }
	case ButtonRelease:
	  if(!opaque_move)
	    MoveOutline(Scr.Root, 0, 0, 0, 0);
	  xl = Event.xmotion.x_root + XOffset;
	  yt = Event.xmotion.y_root + YOffset;

	  /* Resist moving windows over the edge of the screen! */
	  if(((xl + Width) >= Scr.MyDisplayWidth)&&
	     ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
	    xl = Scr.MyDisplayWidth - Width - tmp_win->bw;
	  if((xl <= 0)&&(xl > -Scr.MoveResistance))
	    xl = 0;
	  if(((yt + Height) >= Scr.MyDisplayHeight)&&
	     ((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance))
	    yt = Scr.MyDisplayHeight - Height - tmp_win->bw;
	  if((yt <= 0)&&(yt > -Scr.MoveResistance))
	    yt = 0;

	  *FinalX = xl;
	  *FinalY = yt;

	  done = TRUE;
	  finished = TRUE;
	  break;

	case MotionNotify:
	  /* update location of the pager_view window */
#ifndef NO_PAGER
	  if((Scr.FvwmPager != NULL)&&
	     (xl < Scr.FvwmPager->frame_x + Scr.FvwmPager->frame_width)&&
	     (xl+Width >  Scr.FvwmPager->frame_x)&&
	     (yt < Scr.FvwmPager->frame_y + Scr.FvwmPager->frame_height)&&
	     (yt+ Height >  Scr.FvwmPager->frame_y)&&(!opaque_move))
	    MoveOutline(Scr.Root,0,0,0,0);
#endif
	  xl = Event.xmotion.x_root;
	  yt = Event.xmotion.y_root;
	  HandlePaging(Scr.MyDisplayWidth,Scr.MyDisplayHeight,&xl,&yt,
		       &delta_x,&delta_y,False);
	  /* redraw the rubberband */
	  xl += XOffset;
	  yt += YOffset;

	  /* Resist moving windows over the edge of the screen! */
	  if(((xl + Width) >= Scr.MyDisplayWidth)&&
	     ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance))
	    xl = Scr.MyDisplayWidth - Width - tmp_win->bw;
	  if((xl <= 0)&&(xl > -Scr.MoveResistance))
	    xl = 0;
	  if(((yt + Height) >= Scr.MyDisplayHeight)&&
	     ((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance))
	    yt = Scr.MyDisplayHeight - Height - tmp_win->bw;
	  if((yt <= 0)&&(yt > -Scr.MoveResistance))
	    yt = 0;

#ifndef NO_PAGER
	  if(Scr.FvwmPager)
	    {
	      pagerwidth = Scr.FvwmPager->frame_width - 
		2*Scr.FvwmPager->boundary_width;
	      pagerheight = Scr.FvwmPager->frame_height - 
		Scr.FvwmPager->title_height - 2*Scr.FvwmPager->boundary_width;
	      
	      MaxW = Scr.VxMax + Scr.MyDisplayWidth;
	      MaxH = Scr.VyMax + Scr.MyDisplayHeight;
	      
	      if(!(tmp_win->flags & STICKY)&&
		 (!(tmp_win->flags&ICONIFIED)||
		  (!(tmp_win->flags&SUPPRESSICON)))&&
		 (!(tmp_win->flags&ICONIFIED)||(!(Scr.flags & StickyIcons))))
		{
		  /* show the actual window */
		  wx = (xl + Scr.Vx)*(int)pagerwidth/MaxW;
		  wy = (yt + Scr.Vy)*(int)pagerheight/MaxH;
		  if((last_x - wx >= 2)||(last_x - wx <= -2)||
		     (last_y - wy >= 2)||(last_y - wy <= -2))
		    {
		      ww = Width*(int)pagerwidth/MaxW;
		      wh = Height*(int)pagerheight/MaxH;
		      if(ww<2)ww=2;
		      if(wh<2)wh=2;
		      XMoveResizeWindow(dpy, 
					tmp_win->pager_view, wx, wy, ww, wh);
		      last_x = wx;
		      last_y = wy;
		    }
		}
	    }
#endif

	  if(!opaque_move)
	    MoveOutline(Scr.Root, xl, yt, Width,Height);
	  else
	    {
	      if (tmp_win->flags & ICONIFIED)
		{
		  tmp_win->icon_x_loc = xl ;
		  tmp_win->icon_xl_loc = xl -
		    (tmp_win->icon_w_width - tmp_win->icon_p_width)/2;
		  tmp_win->icon_y_loc = yt; 
		  if(tmp_win->icon_pixmap_w != None)
		    XMoveWindow (dpy, tmp_win->icon_pixmap_w,
				 tmp_win->icon_x_loc,yt);
                  else if (tmp_win->icon_w != None)
		    XMoveWindow(dpy, tmp_win->icon_w,tmp_win->icon_xl_loc,
				yt+tmp_win->icon_p_height);
		    
		}
	      else
		XMoveWindow(dpy,tmp_win->frame,xl,yt);
	    }
	  DisplayPosition(tmp_win,xl+Scr.Vx,yt+Scr.Vy,False);
	  done = TRUE;
	  break;

	default:
	  break;
	}
      if(!done)
	{
	  if(!opaque_move)
	    MoveOutline(Scr.Root,0,0,0,0);
   	  DispatchEvent();
	  if(!opaque_move)
	    MoveOutline(Scr.Root, xl, yt, Width, Height);
	}
    }
}