Esempio n. 1
0
File: move.c Progetto: 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);
	}
    }
}
Esempio n. 2
0
/***********************************************************************
 *
 *  Procedure:
 *	HandleEnterNotify - EnterNotify event handler
 *
 ************************************************************************/
void HandleEnterNotify()
{
  XEnterWindowEvent *ewp = &Event.xcrossing;
  XEvent d;

  DBUG("HandleEnterNotify","Routine Entered");

  /* look for a matching leaveNotify which would nullify this enterNotify */
  if(XCheckTypedWindowEvent (dpy, ewp->window, LeaveNotify, &d))
    {
      /*
         RBW - if we're in startup, this is a coerced focus, so we don't
         want to save the event time, or exit prematurely.
      */
      if (! fFvwmInStartup)
        {
          StashEventTime(&d);
          if((d.xcrossing.mode==NotifyNormal)&&
	     (d.xcrossing.detail!=NotifyInferior))
	    return;
        }
    }

/* an EnterEvent in one of the PanFrameWindows activates the Paging */
#ifndef NON_VIRTUAL
  if (ewp->window==Scr.PanFrameTop.win
      || ewp->window==Scr.PanFrameLeft.win
      || ewp->window==Scr.PanFrameRight.win
      || ewp->window==Scr.PanFrameBottom.win )
  {
    int delta_x=0, delta_y=0;
    /* this was in the HandleMotionNotify before, HEDU */
    HandlePaging(Scr.EdgeScrollX,Scr.EdgeScrollY,
                 &Event.xcrossing.x_root,&Event.xcrossing.y_root,
                 &delta_x,&delta_y,True);
    return;
  }
#endif /* NON_VIRTUAL */

  /* multi screen? */
  if (Event.xany.window == Scr.Root)
  {
    if (!Scr.Focus || (!(Scr.Focus->flags&ClickToFocus)&&
                       !(Scr.Focus->flags&SloppyFocus)))
    {
      SetFocus(Scr.NoFocusWin,NULL,1);
    }
    if (Scr.ColormapFocus == COLORMAP_FOLLOWS_MOUSE)
    {
      InstallWindowColormaps(NULL);
    }
    return;
  }

  /* make sure its for one of our windows */
  if (!Tmp_win)
    return;

  if(!(Tmp_win->flags & ClickToFocus))
    {
      SetFocus(Tmp_win->w,Tmp_win,1);
    }
  if (Scr.ColormapFocus == COLORMAP_FOLLOWS_MOUSE)
  {
    if((!(Tmp_win->flags & ICONIFIED))&&(Event.xany.window == Tmp_win->w))
      InstallWindowColormaps(Tmp_win);
    else
      InstallWindowColormaps(NULL);
  }
  return;
}