diff --git a/doc/modules/FvwmPager.adoc b/doc/modules/FvwmPager.adoc index f045b424b..c355f585e 100644 --- a/doc/modules/FvwmPager.adoc +++ b/doc/modules/FvwmPager.adoc @@ -15,6 +15,12 @@ both desk numbers are omitted, the current desk is used instead. If you use an asterisk '*' in place of _first desk_ the pager will always show the current desktop, even when you switch desks. +FvwmPager will compute its initial window size based on your monitor(s) +configuration. By default it makes a page 1/32 the size of your monitor(s) +resolution (see _DeskTopScale_) and matches either the global aspect ratio +or a single monitor if _Monitor_ is set. FvwmPager will preserve this +aspect ratio when you resize it. See the _Geometry_ option for more info. + Example lines to put in your .fvwm2rc: .... @@ -143,9 +149,16 @@ The invocation method was shown in the synopsis section *FvwmPager: Geometry geometry:: Completely or partially specifies the pager windows location and - geometry, in standard X11 notation. In order to maintain an - undistorted aspect ratio, you might want to leave out either the width - or height dimension of the geometry specification. + geometry, in standard X11 notation. If both width and height are + set, FvwmPager will use that size and no longer preserve the + aspect ratio when resized. If you wish to maintain an undistorted + aspect ratio, you can set one dimension to zero. For example + '400x0' will make a 400 pixel wide window whose height matches + the aspect ratio and will also preserve aspect ratio when resized. ++ +*Note*: FvwmPager's dimensions will be slightly adjusted to ensure +every page shown has the exact same number of pixels. So the actual +size may be slightly different than the specified size. *FvwmPager: Rows rows:: Tells fvwm how many rows of desks to use when laying out the pager window. diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c index ff37fb21f..1906be567 100644 --- a/modules/FvwmPager/x_pager.c +++ b/modules/FvwmPager/x_pager.c @@ -405,14 +405,14 @@ void draw_desk_background(int i, int page_w, int page_h) char *pager_name = "Fvwm Pager"; XSizeHints sizehints = { - (PMinSize | PResizeInc | PBaseSize | PWinGravity), - 0, 0, 100, 100, /* x, y, width and height */ - 1, 1, /* Min width and height */ - 0, 0, /* Max width and height */ - 1, 1, /* Width and height increments */ - {0, 0}, {0, 0}, /* Aspect ratio - not used */ - 1, 1, /* base size */ - (NorthWestGravity) /* gravity */ + (PMinSize | PResizeInc | PBaseSize | PWinGravity), /* flags */ + 0, 0, 100, 100, /* x, y, width and height (legacy) */ + 1, 1, /* Min width and height */ + 0, 0, /* Max width and height */ + 1, 1, /* Width and height increments */ + {0, 0}, {0, 0}, /* Aspect ratio */ + 1, 1, /* base size */ + (NorthWestGravity) /* gravity */ }; void initialize_balloon_window(void) @@ -456,11 +456,12 @@ void initialize_pager(void) extern char *WindowBack, *WindowFore, *WindowHiBack, *WindowHiFore; extern char *BalloonFont; extern char *font_string, *smallFont; - int n,m,w,h,i,x,y; + int w = 0, h = 0, x = 0, y = 0, i = 0; XGCValues gcv; char dash_list[2]; FlocaleFont *balloon_font; struct fpmonitor *mon = fpmonitor_this(); + int VxPages = mon->virtual_scr.VxPages, VyPages = mon->virtual_scr.VyPages; /* I don't think that this is necessary - just let pager die */ /* domivogt (07-mar-1999): But it is! A window being moved in the pager @@ -543,9 +544,6 @@ void initialize_pager(void) fore_pix,back_pix,Pdepth); } - n = mon->virtual_scr.VxMax / (mon->x + mon->w); //mon->virtual_scr.MyDisplayWidth; - m = mon->virtual_scr.VyMax / (mon->y + mon->h); //mon->virtual_scr.MyDisplayHeight; - /* Size the window */ if(Rows < 0) { @@ -579,34 +577,64 @@ void initialize_pager(void) Rows++; } - sizehints.width_inc = Columns*(n+1); - sizehints.height_inc = Rows*(m+1); - sizehints.base_width = Columns * n + Columns - 1; - sizehints.base_height = Rows * (m + label_h + 1) - 1; - - int vWidth = mon->virtual_scr.VxPages * (mon->x + mon->w); - int vHeight = mon->virtual_scr.VyPages * (mon->y + mon->h); + /* Set window size if not fully set by user to match */ + /* aspect ratio of monitor(s) being shown. */ + if ( window_w == 0 || window_h == 0 ) { + int vWidth = monitor_get_all_widths(); + int vHeight = monitor_get_all_heights(); + if (monitor_to_track != NULL) { + vWidth = mon->w; + vHeight = mon->h; + } + + if (window_w > 0) { + window_h = (window_w * vHeight) / vWidth + + label_h * Rows + Rows; + } else if (window_h > label_h * Rows) { + window_w = ((window_h - label_h * Rows + Rows) * + vWidth) / vHeight + Columns; + } else { + window_w = (VxPages * vWidth * Columns) / Scr.VScale + + Columns; + window_h = (VyPages * vHeight * Rows) / Scr.VScale + + label_h * Rows + Rows; + } + sizehints.flags = (sizehints.flags | PAspect); + sizehints.min_aspect.x = sizehints.max_aspect.x = window_w; + sizehints.min_aspect.y = sizehints.max_aspect.y = window_h; + } + /* Resize increments are one pixel per visible page. */ + sizehints.width_inc = Columns * VxPages; + sizehints.height_inc = Rows * VyPages; + /* Set Min size for 1 pixel pages */ + sizehints.min_width = VxPages * Columns + Columns - 1; + sizehints.min_height = (VyPages + label_h + 1) * Rows - 1; + sizehints.base_width = sizehints.min_width; + sizehints.base_height = sizehints.min_height; + + /* Adjust window size to be even multiples of increment size. */ + if (window_w > 0) { + window_w = (window_w - sizehints.base_width) / + sizehints.width_inc; + window_w = window_w * sizehints.width_inc + + sizehints.base_width; + } + if (window_h > 0) { + window_h = (window_h - sizehints.base_height) / + sizehints.height_inc; + window_h = window_h * sizehints.height_inc + + sizehints.base_height; + } + if (sizehints.min_aspect.x > 0) { + sizehints.min_aspect.x = window_w; + sizehints.min_aspect.y = window_h; + sizehints.max_aspect.x = window_w; + sizehints.max_aspect.y = window_h - label_h * Rows; + } + + desk_w = (window_w - Columns + 1) / Columns; + desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; - if (window_w > 0) - { - window_w = (window_w - sizehints.base_width) / sizehints.width_inc; - window_w = window_w * sizehints.width_inc + sizehints.base_width; - } - else - { - window_w = Columns * (vWidth / Scr.VScale + n) + Columns - 1; - } - if (window_h > 0) - { - window_h = (window_h - sizehints.base_height) / sizehints.height_inc; - window_h = window_h * sizehints.height_inc + sizehints.base_height; - } - else - { - window_h = Rows * (vHeight / Scr.VScale + m + label_h + 1) - 1; - } - desk_w = (window_w - Columns + 1) / Columns; - desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; if (is_transient) { rectangle screen_g; @@ -617,6 +645,8 @@ void initialize_pager(void) FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); + /* FIXME: Recalculate what to do if window is off screen. */ + /* Leaving alone for now */ if (window_w + window_x > screen_g.x + screen_g.width) { window_x = screen_g.x + screen_g.width - mon->w; //mon->virtual_scr.MyDisplayWidth; @@ -689,12 +719,12 @@ void initialize_pager(void) attributes.event_mask = (StructureNotifyMask| ExposureMask); if(icon_w < 1) - icon_w = (window_w - Columns+1)/Columns; + icon_w = (window_w - Columns + 1) / Columns; if(icon_h < 1) - icon_h = (window_h - Rows* label_h - Rows + 1)/Rows; + icon_h = (window_h - Rows * label_h - Rows + 1) / Rows; - icon_w = (icon_w / (n+1)) *(n+1)+n; - icon_h = (icon_h / (m+1)) *(m+1)+m; + icon_w = (icon_w / (VxPages + 1)) * (VxPages + 1) + VxPages; + icon_h = (icon_h / (VyPages + 1)) * (VyPages + 1) + VyPages; icon_win = XCreateWindow (dpy, Scr.Root, window_x, window_y, icon_w, icon_h, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); @@ -910,8 +940,8 @@ void initialize_pager(void) : Colorset[Desks[i].highcolorset].bg; } - w = w / (n + 1); - h = desk_h / (m + 1); + w = w / (VxPages + 1); + h = desk_h / (VyPages + 1); Desks[i].CPagerWin=XCreateWindow(dpy, Desks[i].w, -32768, -32768, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); @@ -1333,11 +1363,12 @@ void ReConfigure(void) { Window root; unsigned border_width, depth; - int n,m,w,h,n1,m1,x,y,i,j,k; + int w,h,x,y,i,j,k; int old_ww; int old_wh; int is_size_changed; struct fpmonitor *mon = fpmonitor_this(); + int VxPages = mon->virtual_scr.VxPages, VyPages = mon->virtual_scr.VyPages; old_ww = window_w; old_wh = window_h; @@ -1348,36 +1379,40 @@ void ReConfigure(void) } is_size_changed = (old_ww != window_w || old_wh != window_h); - n1 = mon->virtual_scr.Vx / mon->virtual_scr.MyDisplayWidth; - m1 = mon->virtual_scr.Vy / mon->virtual_scr.MyDisplayHeight; - n = mon->virtual_scr.VxMax / mon->virtual_scr.MyDisplayWidth; - m = mon->virtual_scr.VyMax / mon->virtual_scr.MyDisplayHeight; + /* Update size hints to new size */ + sizehints.width_inc = Columns * VxPages; + sizehints.height_inc = Rows * VyPages; + sizehints.min_width = VxPages * Columns + Columns - 1; + sizehints.min_height = (VyPages + label_h + 1) * Rows - 1; + sizehints.base_width = sizehints.min_width; + sizehints.base_height = sizehints.min_height; + + /* Adjust window size to be whole multiples of increment size. */ + if (window_w > 0) { + window_w = (window_w - sizehints.base_width) / + sizehints.width_inc; + window_w = window_w * sizehints.width_inc + + sizehints.base_width; + } + if (window_h > 0) { + window_h = (window_h - sizehints.base_height) / + sizehints.height_inc; + window_h = window_h * sizehints.height_inc + + sizehints.base_height; + } - sizehints.width_inc = Columns * (n + 1); - sizehints.height_inc = Rows * (m + 1); - sizehints.base_width = Columns * n + Columns - 1; - sizehints.base_height = Rows*(m + label_h+1) - 1; - sizehints.min_width = sizehints.base_width; - sizehints.min_height = sizehints.base_height; - if (window_w > 0) - { - window_w = (window_w - sizehints.base_width) / sizehints.width_inc; - window_w = window_w * sizehints.width_inc + sizehints.base_width; - } - if (window_h > 0) - { - window_h = (window_h - sizehints.base_height) / sizehints.height_inc; - window_h = window_h * sizehints.height_inc + sizehints.base_height; - } desk_w = (window_w - Columns + 1) / Columns; desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; - w = (desk_w - n)/(n+1); - h = (desk_h - m)/(m+1); + w = (desk_w - VxPages)/(VxPages + 1); + h = (desk_h - VyPages)/(VyPages + 1); XSetWMNormalHints(dpy,Scr.Pager_w,&sizehints); - x = (desk_w - n) * mon->virtual_scr.Vx / mon->virtual_scr.VWidth + n1; - y = (desk_h - m) * mon->virtual_scr.Vy / mon->virtual_scr.VHeight + m1; + /* FIXME: This needs to be looked at for per-monitor configuration */ + x = (desk_w - VxPages) * mon->virtual_scr.Vx / mon->virtual_scr.VWidth + + mon->virtual_scr.Vx / mon->virtual_scr.MyDisplayWidth; + y = (desk_h - VyPages) * mon->virtual_scr.Vy / mon->virtual_scr.VHeight + + mon->virtual_scr.Vy / mon->virtual_scr.MyDisplayHeight; for(k=0;k