/* * geom.c -- backend-neutral window geometry constraint functions * * Contains only pure geometry arithmetic: no Xlib, no display calls. * Unit tests link this file standalone (without -lX11). * * Phase 5: extracted from window.c. */ #include "wconfig.h" #include "WindowMaker.h" /* WPreferences, wPreferences */ #include "screen.h" /* WScreen */ #include "window.h" /* WWindow, WNormalHints */ #include "geom.h" /* *---------------------------------------------------------------------- * wWindowConstrainSize-- * Constrains size for the client window, taking the maximal size, * window resize increments and other size hints into account. * * Returns: * The closest size to what was given that the client window can * have. * *---------------------------------------------------------------------- */ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nheight) { int width = (int)*nwidth; int height = (int)*nheight; int winc = 1; int hinc = 1; int minW = 1, minH = 1; int maxW = wwin->screen_ptr->scr_width * 2; int maxH = wwin->screen_ptr->scr_height * 2; int minAX = -1, minAY = -1; int maxAX = -1, maxAY = -1; int baseW = 0; int baseH = 0; if (wwin->normal_hints) { if (!wwin->flags.maximized) { winc = wwin->normal_hints->width_inc; hinc = wwin->normal_hints->height_inc; } if (wwin->normal_hints->min_width > minW) minW = wwin->normal_hints->min_width; if (wwin->normal_hints->min_height > minH) minH = wwin->normal_hints->min_height; if (wwin->normal_hints->max_width < maxW) maxW = wwin->normal_hints->max_width; if (wwin->normal_hints->max_height < maxH) maxH = wwin->normal_hints->max_height; if (wwin->normal_hints->flags & WNH_P_ASPECT) { minAX = wwin->normal_hints->min_aspect.x; minAY = wwin->normal_hints->min_aspect.y; maxAX = wwin->normal_hints->max_aspect.x; maxAY = wwin->normal_hints->max_aspect.y; } baseW = wwin->normal_hints->base_width; baseH = wwin->normal_hints->base_height; } /* trust the mins provided by the client but not the maxs */ if (width < minW) width = minW; if (height < minH) height = minH; /* if only one dimension is over the top, set a default 4/3 ratio */ if (width > maxW && height < maxH) width = height * 4 / 3; else if(height > maxH && width < maxW) height = width * 3 / 4; else if(width > maxW && height > maxH) { /* if both are over the top, set size to almost fullscreen */ height = wwin->screen_ptr->scr_height - 2 * wPreferences.icon_size; width = wwin->screen_ptr->scr_width - 2 * wPreferences.icon_size; } /* aspect ratio code borrowed from olwm */ if (minAX > 0) { /* adjust max aspect ratio */ if (!(maxAX == 1 && maxAY == 1) && width * maxAY > height * maxAX) { if (maxAX > maxAY) { height = (width * maxAY) / maxAX; if (height > maxH) { height = maxH; width = (height * maxAX) / maxAY; } } else { width = (height * maxAX) / maxAY; if (width > maxW) { width = maxW; height = (width * maxAY) / maxAX; } } } /* adjust min aspect ratio */ if (!(minAX == 1 && minAY == 1) && width * minAY < height * minAX) { if (minAX > minAY) { height = (width * minAY) / minAX; if (height < minH) { height = minH; width = (height * minAX) / minAY; } } else { width = (height * minAX) / minAY; if (width < minW) { width = minW; height = (width * minAY) / minAX; } } } } if (!wwin->flags.maximized) { if (baseW != 0) width = (((width - baseW) / winc) * winc) + baseW; else width = (((width - minW) / winc) * winc) + minW; if (baseH != 0) height = (((height - baseH) / hinc) * hinc) + baseH; else height = (((height - minH) / hinc) * hinc) + minH; } /* broken stupid apps may cause preposterous values for these.. */ if (width > 0) *nwidth = width; if (height > 0) *nheight = height; } void wWindowCropSize(WWindow *wwin, unsigned int maxW, unsigned int maxH, unsigned int *width, unsigned int *height) { int baseW = 0, baseH = 0; int winc = 1, hinc = 1; if (wwin->normal_hints) { baseW = wwin->normal_hints->base_width; baseH = wwin->normal_hints->base_height; winc = wwin->normal_hints->width_inc; hinc = wwin->normal_hints->height_inc; } if (*width > maxW) *width = maxW - (maxW - baseW) % winc; if (*height > maxH) *height = maxH - (maxH - baseH) % hinc; }