/* * * 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; }
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; } }