Ejemplo n.º 1
0
/*
 *
 *  Procedure:
 *      constrain_size - adjust the given width and height to account for the
 *              constraints imposed by size hints
 */
void constrain_size(
	FvwmWindow *fw, const XEvent *e, int *widthp, int *heightp,
	int xmotion, int ymotion, int flags)
{
	size_rect min;
	size_rect max;
	size_rect inc;
	size_rect base;
	size_rect round_up;
	size_rect d;
	size_rect old;
	size_borders b;

	if (DO_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw) == 1)
	{
		return;
	}
	if (HAS_NEW_WM_NORMAL_HINTS(fw))
	{
		/* get the latest size hints */
		XSync(dpy, 0);
		GetWindowSizeHints(fw);
		SET_HAS_NEW_WM_NORMAL_HINTS(fw, 0);
	}
	if (IS_MAXIMIZED(fw) && (flags & CS_UPDATE_MAX_DEFECT))
	{
		*widthp += fw->g.max_defect.width;
		*heightp += fw->g.max_defect.height;
	}
	/* gcc 4.1.1 warns about these not being initialized at the end,
	 * but the conditions for the use are the same...*/
	old.width = *widthp;
	old.height = *heightp;

	d.width = *widthp;
	d.height = *heightp;
	get_window_borders(fw, &b);
	d.width -= b.total_size.width;
	d.height -= b.total_size.height;

	min.width = fw->hints.min_width;
	min.height = fw->hints.min_height;
	if (min.width < fw->min_window_width - b.total_size.width)
	{
		min.width = fw->min_window_width - b.total_size.width;
	}
	if (min.height < fw->min_window_height - b.total_size.height)
	{
		min.height =
			fw->min_window_height - b.total_size.height;
	}

	max.width = fw->hints.max_width;
	max.height =  fw->hints.max_height;
	if (max.width > fw->max_window_width - b.total_size.width)
	{
		max.width = fw->max_window_width - b.total_size.width;
	}
	if (max.height > fw->max_window_height - b.total_size.height)
	{
		max.height =
			fw->max_window_height - b.total_size.height;
	}

	if (min.width > max.width)
	{
		min.width = max.width;
	}
	if (min.height > max.height)
	{
		min.height = max.height;
	}

	base.width = fw->hints.base_width;
	base.height = fw->hints.base_height;

	inc.width = fw->hints.width_inc;
	inc.height = fw->hints.height_inc;

	/*
	 * First, clamp to min and max values
	 */
	if (d.width < min.width)
	{
		d.width = min.width;
	}
	if (d.height < min.height)
	{
		d.height = min.height;
	}
	if (d.width > max.width)
	{
		d.width = max.width;
	}
	if (d.height > max.height)
	{
		d.height = max.height;
	}

	/*
	 * Second, round to base + N * inc (up or down depending on resize
	 * type) if rounding up store amount
	 */
	if (!(flags & CS_ROUND_UP))
	{
		d.width = ((d.width - base.width) / inc.width) *
			inc.width + base.width;
		d.height = ((d.height - base.height) / inc.height) *
			inc.height + base.height;
	}
	else
	{
		round_up.width = d.width;
		round_up.height = d.height;
		d.width = ((d.width - base.width + inc.width - 1) /
			   inc.width) * inc.width + base.width;
		d.height = ((d.height - base.height + inc.height - 1) /
			    inc.height) * inc.height + base.height;
		round_up.width = d.width - round_up.width;
		round_up.height = d.height - round_up.height;
	}

	/*
	 * Step 2a: check we didn't move the edge off screen in interactive
	 * moves
	 */
	if ((flags & CS_ROUND_UP) && e != NULL && e->type == MotionNotify)
	{
		if (xmotion > 0 && e->xmotion.x_root < round_up.width)
		{
			d.width -= inc.width;
		}
		else if (
			xmotion < 0 && e->xmotion.x_root >=
			Scr.MyDisplayWidth - round_up.width)
		{
			d.width -= inc.width;
		}
		if (ymotion > 0 && e->xmotion.y_root < round_up.height)
		{
			d.height -= inc.height;
		}
		else if (
			ymotion < 0 && e->xmotion.y_root >=
			Scr.MyDisplayHeight - round_up.height)
		{
			d.height -= inc.height;
		}
	}

	/*
	 * Step 2b: Check that we didn't violate min and max.
	 */
	if (d.width < min.width)
	{
		d.width += inc.width;
	}
	if (d.height < min.height)
	{
		d.height += inc.height;
	}
	if (d.width > max.width)
	{
		d.width -= inc.width;
	}
	if (d.height > max.height)
	{
		d.height -= inc.height;
	}

	/*
	 * Third, adjust for aspect ratio
	 */
	if (fw->hints.flags & PAspect)
	{
		__cs_handle_aspect_ratio(
			&d, fw, d, base, inc, min, max, xmotion, ymotion,
			flags);
	}

	/*
	 * Fourth, account for border width and title height
	 */
	*widthp = d.width + b.total_size.width;
	*heightp = d.height + b.total_size.height;
	if (IS_MAXIMIZED(fw) && (flags & CS_UPDATE_MAX_DEFECT))
	{
		/* update size defect for maximized window */
		fw->g.max_defect.width = old.width - *widthp;
		fw->g.max_defect.height = old.height - *heightp;
	}

	return;
}
Ejemplo n.º 2
0
void HandlePropertyNotify()
{
  XTextProperty text_prop;
  Boolean       OnThisPage    =  False;

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

  if ((!Tmp_win)||
      (XGetGeometry(dpy, Tmp_win->w, &JunkRoot, &JunkX, &JunkY,
		    &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0))
    return;

  /*
      Make sure at least part of window is on this page
      before giving it focus...
  */
  if ( (Tmp_win->Desk == Scr.CurrentDesk) &&
       ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 &&
          Tmp_win->frame_x < Scr.MyDisplayWidth) &&
         ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 &&
          Tmp_win->frame_y < Scr.MyDisplayHeight)
       )
     )
    {
      OnThisPage  =  True;
    }

  switch (Event.xproperty.atom)
    {
    case XA_WM_TRANSIENT_FOR:
      {
        if(XGetTransientForHint(dpy, Tmp_win->w, &Tmp_win->transientfor))
        {
           Tmp_win->flags |= TRANSIENT;
           RaiseWindow(Tmp_win);
        }
        else
        {
           Tmp_win->flags &= ~TRANSIENT;
        }
      }
      break;

    case XA_WM_NAME:
      if (!XGetWMName(dpy, Tmp_win->w, &text_prop))
	return;

      free_window_names (Tmp_win, True, False);

      Tmp_win->name = (char *)text_prop.value;
      if (Tmp_win->name && strlen(Tmp_win->name) > 200)
	/* limit to prevent hanging X server */
	Tmp_win->name[200] = 0;

      if (Tmp_win->name == NULL)
        Tmp_win->name = NoName;
      BroadcastName(M_WINDOW_NAME,Tmp_win->w,Tmp_win->frame,
		    (unsigned long)Tmp_win,Tmp_win->name);

      /* fix the name in the title bar */
      if(!(Tmp_win->flags & ICONIFIED))
	SetTitleBar(Tmp_win,(Scr.Hilite==Tmp_win),True);

      /*
       * if the icon name is NoName, set the name of the icon to be
       * the same as the window
       */
      if (Tmp_win->icon_name == NoName)
	{
	  Tmp_win->icon_name = Tmp_win->name;
	  BroadcastName(M_ICON_NAME,Tmp_win->w,Tmp_win->frame,
			(unsigned long)Tmp_win,Tmp_win->icon_name);
	  RedoIconName(Tmp_win);
	}
      break;

    case XA_WM_ICON_NAME:
      if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop))
	return;
      free_window_names (Tmp_win, False, True);
      Tmp_win->icon_name = (char *) text_prop.value;
      if (Tmp_win->icon_name && strlen(Tmp_win->icon_name) > 200)
	/* limit to prevent hanging X server */
	Tmp_win->icon_name[200] = 0;
      if (Tmp_win->icon_name == NULL)
        Tmp_win->icon_name = NoName;
      BroadcastName(M_ICON_NAME,Tmp_win->w,Tmp_win->frame,
		    (unsigned long)Tmp_win,Tmp_win->icon_name);
      RedoIconName(Tmp_win);
      break;

    case XA_WM_HINTS:
      if (Tmp_win->wmhints)
	XFree ((char *) Tmp_win->wmhints);
      Tmp_win->wmhints = XGetWMHints(dpy, Event.xany.window);

      if(Tmp_win->wmhints == NULL)
	return;

      if((Tmp_win->wmhints->flags & IconPixmapHint)||
	 (Tmp_win->wmhints->flags & IconWindowHint))
	if(Tmp_win->icon_bitmap_file == Scr.DefaultIcon)
	  Tmp_win->icon_bitmap_file = (char *)0;

      if((Tmp_win->wmhints->flags & IconPixmapHint)||
         (Tmp_win->wmhints->flags & IconWindowHint))
	{
	  if (!(Tmp_win->flags & SUPPRESSICON))
	    {
              if (Tmp_win->icon_w)
                XDestroyWindow(dpy,Tmp_win->icon_w);
	      XDeleteContext(dpy, Tmp_win->icon_w, FvwmContext);
	      if(Tmp_win->flags & ICON_OURS)
		{
		  if(Tmp_win->icon_pixmap_w != None)
		    {
		      XDestroyWindow(dpy,Tmp_win->icon_pixmap_w);
		      XDeleteContext(dpy, Tmp_win->icon_pixmap_w, FvwmContext);
		    }
		}
	      else
		XUnmapWindow(dpy,Tmp_win->icon_pixmap_w);
	    }
          Tmp_win->icon_w = None;
          Tmp_win->icon_pixmap_w = None;
	  Tmp_win->iconPixmap = (Window)NULL;
	  if(Tmp_win->flags & ICONIFIED)
	    {
	      Tmp_win->flags &= ~ICONIFIED;
	      Tmp_win->flags &= ~ICON_UNMAPPED;
	      CreateIconWindow(Tmp_win,
			       Tmp_win->icon_x_loc,Tmp_win->icon_y_loc);
	      BroadcastPacket(M_ICONIFY, 7,
                              Tmp_win->w, Tmp_win->frame,
                              (unsigned long)Tmp_win,
                              Tmp_win->icon_x_loc, Tmp_win->icon_y_loc,
                              Tmp_win->icon_w_width, Tmp_win->icon_w_height);
	      BroadcastConfig(M_CONFIGURE_WINDOW, Tmp_win);

	      if (!(Tmp_win->flags & SUPPRESSICON))
		{
		  LowerWindow(Tmp_win);
		  AutoPlace(Tmp_win);
		  if(Tmp_win->Desk == Scr.CurrentDesk)
		    {
                      if(Tmp_win->icon_w)
                        XMapWindow(dpy, Tmp_win->icon_w);
		      if(Tmp_win->icon_pixmap_w != None)
			XMapWindow(dpy, Tmp_win->icon_pixmap_w);
		    }
		}
	      Tmp_win->flags |= ICONIFIED;
	      DrawIconWindow(Tmp_win);
	    }
	}
      break;

    case XA_WM_NORMAL_HINTS:
      GetWindowSizeHints (Tmp_win);
#if 0
      /*
      ** ckh - not sure why this next stuff was here, but fvwm 1.xx
      ** didn't do this, and it seems to cause a bug when changing
      ** fonts in XTerm
      */
      {
	int new_width, new_height;
	new_width = Tmp_win->frame_width;
	new_height = Tmp_win->frame_height;
	ConstrainSize(Tmp_win, &new_width, &new_height, False, 0, 0);
	if((new_width != Tmp_win->frame_width)||
	   (new_height != Tmp_win->frame_height))
	  SetupFrame(Tmp_win,Tmp_win->frame_x, Tmp_win->frame_y,
		     new_width,new_height,False);
      }
#endif /* 0 */
      BroadcastConfig(M_CONFIGURE_WINDOW,Tmp_win);
      break;

    default:
      if(Event.xproperty.atom == _XA_WM_PROTOCOLS)
	FetchWmProtocols (Tmp_win);
      else if (Event.xproperty.atom == _XA_WM_COLORMAP_WINDOWS)
	{
	  FetchWmColormapWindows (Tmp_win);	/* frees old data */
	  ReInstallActiveColormap();
	}
      else if(Event.xproperty.atom == _XA_WM_STATE)
	{
	  if((Tmp_win != NULL)&&(Tmp_win->flags & ClickToFocus)
	     &&(Tmp_win == Scr.Focus))
	    {
              if (OnThisPage)
              {
	        Scr.Focus = NULL;
	        SetFocus(Tmp_win->w,Tmp_win,0);
              }
	    }
	}
      break;
    }
}