diff options
-rw-r--r-- | ChangeLog | 42 | ||||
-rw-r--r-- | doc/wm.n | 6 | ||||
-rw-r--r-- | tests/unixWm.test | 92 | ||||
-rw-r--r-- | tests/wm.test | 143 | ||||
-rw-r--r-- | unix/tkUnixWm.c | 88 | ||||
-rw-r--r-- | win/tkWinWm.c | 57 |
6 files changed, 367 insertions, 61 deletions
@@ -1,5 +1,47 @@ 2003-03-11 Mo DeJong <mdejong@users.sourceforge.net> + * doc/wm.n (minimize, maximize): Remove claim + that the resizable command keeps scripts from + changing the size of windows since it is + not true. The resizable command only applies + to user sizing via user interaction. + * tests/unixWm.test: Replace broken tests with + the nonPortable constraint with new tests for + maxsize and minsize options. These tests + verify that setting the minsize and maxsize + will resize the window if needed, and that + the wm hints will be updated with the new sizes. + * tests/wm.test: Add an exhaustive set of tests + for the wm maxsize and wm minsize commands. + These tests verify that setting the minsize + and maxsize will resize the window if needed. + These tests have only been run under Win98 + and Window Maker under Linux, so further tweaking + may be needed for other systems. + * unix/tkUnixWm.c (UpdateGeometryInfo, UpdateSizeHints): + Fixup comments and initialization for the minWidth, + minHeight, maxWidth, maxHeight, width, and height + members of the WmInfo struct. Check to ensure + that a new toplevel window size is not larger + than the maxsize or smaller than the minsize + when updating the geometry at idle time. + Pass new width and height values to the + UpdateSizeHints method so that it can properly + set the window min and max sizes for a window + that cannot be resized by the user. This fixes + a bug where the window resizes back to the original + size when the user clicks on the window border. + * win/tkWinWm.c (UpdateGeometryInfo): + Fixup comments and initialization for the minWidth, + minHeight, maxWidth, maxHeight, width, and height + members of the WmInfo struct. Check to ensure + that a new toplevel window size is not larger + than the maxsize or smaller than the minsize + when updating the geometry at idle time. + [Patch 568861] + +2003-03-11 Mo DeJong <mdejong@users.sourceforge.net> + * generic/tkGrid.c (GridStructureProc, ConfigureSlaves): Check for a NULL masterPtr and slavePtr in the GridStructureProc code to ensure that a Gridder @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: wm.n,v 1.11 2002/07/16 18:06:41 vincentdarley Exp $ +'\" RCS: @(#) $Id: wm.n,v 1.12 2003/03/12 00:25:41 mdejong Exp $ '\" .so man.macros .TH wm n 8.4 Tk "Tk Built-In Commands" @@ -312,8 +312,6 @@ specified, then the command returns an empty string. Otherwise it returns a Tcl list with two elements, which are the maximum width and height currently in effect. The maximum size defaults to the size of the screen. -If resizing has been disabled with the \fBwm resizable\fR command, -then this command has no effect. See the sections on geometry management below for more information. .TP \fBwm minsize \fIwindow\fR ?\fIwidth height\fR? @@ -328,8 +326,6 @@ specified, then the command returns an empty string. Otherwise it returns a Tcl list with two elements, which are the minimum width and height currently in effect. The minimum size defaults to one pixel in each dimension. -If resizing has been disabled with the \fBwm resizable\fR command, -then this command has no effect. See the sections on geometry management below for more information. .TP \fBwm overrideredirect \fIwindow\fR ?\fIboolean\fR? diff --git a/tests/unixWm.test b/tests/unixWm.test index 4bb5379..9c77197 100644 --- a/tests/unixWm.test +++ b/tests/unixWm.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: unixWm.test,v 1.29 2002/11/07 22:27:04 mdejong Exp $ +# RCS: @(#) $Id: unixWm.test,v 1.30 2003/03/12 00:25:41 mdejong Exp $ package require tcltest 2.2 namespace import -force tcltest::configure @@ -988,35 +988,83 @@ test unixWm-27.7 {Tk_WmCmd procedure, "iconwindow" option, withdrawing icon} { set result } {normal 1 icon 0} -test unixWm-28.1 {Tk_WmCmd procedure, "maxsize" option} {nonPortable} { - wm maxsize .t -} {1137 870} - -test unixWm-28.2 {Tk_WmCmd procedure, "maxsize" option} {nonPortable} { - # Not portable, because some window managers let applications override - # minsize and maxsize. - - wm maxsize .t 200 150 - wm geom .t 300x200 - update - list [winfo width .t] [winfo height .t] -} {200 150} - catch {destroy .t} catch {destroy .icon} toplevel .t -width 100 -height 50 wm geom .t +0+0 update -test unixWm-29.1 {Tk_WmCmd procedure, "minsize" option} {nonPortable} { - # Not portable, because some window managers let applications override - # minsize and maxsize. +test unixWm-28.1 {Tk_WmCmd procedure, "maxsize" option, setting the + maxsize should update WM_NORMAL_HINTS} { + destroy .t + toplevel .t + wm maxsize .t 300 300 + update + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 7] [lindex $hints 8] +} {300 300} - wm minsize .t 150 100 - wm geom .t 50x50 +test unixWm-28.2 {Tk_WmCmd procedure, "maxsize" option, setting the + maxsize to a value smaller than the current size should + set the maxsize in WM_NORMAL_HINTS} { + destroy .t + toplevel .t + wm geom .t 400x400 + wm maxsize .t 300 300 update - list [winfo width .t] [winfo height .t] -} {150 100} + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 7] [lindex $hints 8] +} {300 300} + +test unixWm-28.3 {Tk_WmCmd procedure, "maxsize" option, setting the + maxsize to a value smaller than the current size should + set the maxsize in WM_NORMAL_HINTS even if the + interactive resizable flag is set to 0} { + destroy .t + toplevel .t + wm geom .t 400x400 + wm resizable .t 0 0 + wm maxsize .t 300 300 + update + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 7] [lindex $hints 8] +} {300 300} + +test unixWm-29.1 {Tk_WmCmd procedure, "minsize" option, setting the + minsize should update WM_NORMAL_HINTS} { + destroy .t + toplevel .t + wm minsize .t 300 300 + update + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 5] [lindex $hints 6] +} {300 300} + +test unixWm-29.2 {Tk_WmCmd procedure, "minsize" option, setting the + minsize to a value larger than the current size should + set the maxsize in WM_NORMAL_HINTS} { + destroy .t + toplevel .t + wm geom .t 200x200 + wm minsize .t 300 300 + update + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 5] [lindex $hints 6] +} {300 300} + +test unixWm-29.3 {Tk_WmCmd procedure, "minsize" option, setting the + minsize to a value larger than the current size should + set the minsize in WM_NORMAL_HINTS even if the + interactive resizable flag is set to 0} { + destroy .t + toplevel .t + wm geom .t 200x200 + wm resizable .t 0 0 + wm minsize .t 300 300 + update + set hints [testprop [testwrapper .t] WM_NORMAL_HINTS] + format {%d %d} [lindex $hints 5] [lindex $hints 6] +} {300 300} catch {destroy .t} catch {destroy .icon} diff --git a/tests/wm.test b/tests/wm.test index e9d2de5..3cffdb2 100644 --- a/tests/wm.test +++ b/tests/wm.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: wm.test,v 1.21 2003/01/28 20:39:19 jenglish Exp $ +# RCS: @(#) $Id: wm.test,v 1.22 2003/03/12 00:25:41 mdejong Exp $ # This file tests window manager interactions that work across # platforms. Window manager tests that only work on a specific @@ -663,12 +663,84 @@ test wm-maxsize-1.5 {usage} { test wm-maxsize-1.6 {usage} { catch {destroy .t2} toplevel .t2 - wm maxsize .t2 200 150 + wm maxsize .t2 300 200 set result [wm maxsize .t2] destroy .t2 set result +} {300 200} + +test wm-maxsize-1.7 {maxsize must be <= screen size} { + destroy .t + toplevel .t + foreach {t_width t_height} [wm maxsize .t] break + set s_width [winfo screenwidth .t] + set s_height [winfo screenheight .t] + expr {($t_width <= $s_width) && ($t_height <= $s_height)} +} 1 + +test wm-maxsize-2.1 {setting the maxsize to a value smaller + than the current size will resize a toplevel} { + destroy .t + toplevel .t -width 300 -height 300 + update + wm maxsize .t 200 150 + # UpdateGeometryInfo invoked at idle + update + lrange [split [wm geom .t] x+] 0 1 } {200 150} +test wm-maxsize-2.2 {setting the maxsize to a value smaller + than the current size will resize a gridded toplevel} { + destroy .t + toplevel .t + wm grid .t 0 0 50 50 + wm geometry .t 6x6 + update + wm maxsize .t 4 3 + # UpdateGeometryInfo invoked at idle + update + lrange [split [wm geom .t] x+] 0 1 +} {4 3} + +test wm-maxsize-2.3 {attempting to resize to a value + bigger than the current maxsize will + set it to the max size} { + destroy .t + toplevel .t -width 200 -height 200 + wm maxsize .t 300 250 + update + wm geom .t 400x300 + update + lrange [split [wm geom .t] x+] 0 1 +} {300 250} + +test wm-maxsize-2.4 {attempting to resize to a value + bigger than the current maxsize will + set it to the max size when gridded} { + destroy .t + toplevel .t + wm grid .t 1 1 50 50 + wm geom .t 4x4 + wm maxsize .t 6 5 + update + wm geom .t 8x6 + update + lrange [split [wm geom .t] x+] 0 1 +} {6 5} + +test wm-maxsize-2.5 {Use max size if window size is not + explicitly set and the reqWidth/reqHeight are + bigger than the max size} { + destroy .t + toplevel .t + pack [frame .t.f -width 400 -height 400] + update idletasks + set req [list [winfo reqwidth .t] \ + [winfo reqheight .t]] + wm maxsize .t 300 300 + update + list $req [lrange [split [wm geom .t] x+] 0 1] +} {{400 400} {300 300}} test wm-minsize-1.1 {usage} { list [catch {wm minsize} msg] $msg @@ -693,12 +765,75 @@ test wm-minsize-1.5 {usage} { test wm-minsize-1.6 {usage} { catch {destroy .t2} toplevel .t2 - wm minsize .t2 200 150 + wm minsize .t2 300 200 set result [wm minsize .t2] destroy .t2 set result -} {200 150} +} {300 200} + +test wm-minsize-2.1 {setting the minsize to a value larger + than the current size will resize a toplevel} { + destroy .t + toplevel .t -width 200 -height 200 + update + wm minsize .t 400 300 + # UpdateGeometryInfo invoked at idle + update + lrange [split [wm geom .t] x+] 0 1 +} {400 300} +test wm-minsize-2.2 {setting the minsize to a value larger + than the current size will resize a gridded toplevel} { + destroy .t + toplevel .t + wm grid .t 1 1 50 50 + wm geom .t 4x4 + update + wm minsize .t 8 8 + # UpdateGeometryInfo invoked at idle + update + lrange [split [wm geom .t] x+] 0 1 +} {8 8} + +test wm-minsize-2.3 {attempting to resize to a value + smaller than the current minsize will set + it to the minsize} { + destroy .t + toplevel .t -width 400 -height 400 + wm minsize .t 300 300 + update + wm geom .t 200x200 + update + lrange [split [wm geom .t] x+] 0 1 +} {300 300} + +test wm-minsize-2.4 {attempting to resize to a value + smaller than the current minsize will set + it to the minsize when gridded} { + destroy .t + toplevel .t + wm grid .t 1 1 50 50 + wm geom .t 8x8 + wm minsize .t 6 6 + update + wm geom .t 4x4 + update + lrange [split [wm geom .t] x+] 0 1 +} {6 6} + +test wm-minsize-2.5 {Use min size if window size is not + explicitly set and the reqWidth/reqHeight are + smaller than the min size} { + destroy .t + toplevel .t + pack [frame .t.f -width 250 -height 250] + update idletasks + set req [list [winfo reqwidth .t] \ + [winfo reqheight .t]] + wm minsize .t 300 300 + update + list $req [lrange [split [wm geom .t] x+] 0 1] +} {{250 250} {300 300}} test wm-overrideredirect-1.1 {usage} { list [catch {wm overrideredirect} msg] $msg diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index 2a87d26..5721b02 100644 --- a/unix/tkUnixWm.c +++ b/unix/tkUnixWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixWm.c,v 1.36 2002/12/27 21:23:04 jenglish Exp $ + * RCS: @(#) $Id: tkUnixWm.c,v 1.37 2003/03/12 00:25:41 mdejong Exp $ */ #include "tkPort.h" @@ -108,9 +108,9 @@ typedef struct TkWmInfo { * window is gridded; otherwise it isn't * gridded. */ int minWidth, minHeight; /* Minimum dimensions of window, in - * grid units, not pixels. */ + * pixels or grid units. */ int maxWidth, maxHeight; /* Maximum dimensions of window, in - * grid units, not pixels. */ + * pixels or grid units. 0 to default.*/ Tk_Window gridWin; /* Identifies the window that controls * gridding for this top-level, or NULL if * the top-level isn't currently gridded. */ @@ -131,7 +131,7 @@ typedef struct TkWmInfo { */ int width, height; /* Desired dimensions of window, specified - * in grid units. These values are + * in pixels or grid units. These values are * set by the "wm geometry" command and by * ConfigureNotify events (for when wm * resizes window). -1 means user hasn't @@ -332,7 +332,8 @@ static void UpdateCommand _ANSI_ARGS_((TkWindow *winPtr)); static void UpdateGeometryInfo _ANSI_ARGS_(( ClientData clientData)); static void UpdateHints _ANSI_ARGS_((TkWindow *winPtr)); -static void UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr)); +static void UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr, + int newWidth, int newHeight)); static void UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr)); static void UpdateWmProtocols _ANSI_ARGS_((WmInfo *wmPtr)); static void WaitForConfigureNotify _ANSI_ARGS_((TkWindow *winPtr, @@ -537,13 +538,15 @@ TkWmNewWindow(winPtr) wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0; wmPtr->hints.icon_mask = None; wmPtr->hints.window_group = None; - wmPtr->minWidth = wmPtr->minHeight = 1; /* * Default the maximum dimensions to the size of the display, minus * a guess about how space is needed for window manager decorations. */ + wmPtr->gridWin = NULL; + wmPtr->minWidth = wmPtr->minHeight = 1; + wmPtr->maxWidth = wmPtr->maxHeight = 0; wmPtr->widthInc = wmPtr->heightInc = 1; wmPtr->minAspect.x = wmPtr->minAspect.y = 1; wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1; @@ -3955,7 +3958,7 @@ UpdateGeometryInfo(clientData) { register TkWindow *winPtr = (TkWindow *) clientData; register WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y, width, height; + int x, y, width, height, min, max; unsigned long serial; wmPtr->flags &= ~WM_UPDATE_PENDING; @@ -3966,9 +3969,10 @@ UpdateGeometryInfo(clientData) * requested depends on (a) the size requested internally * by the window's widgets, (b) the size requested by the * user in a "wm geometry" command or via wm-based interactive - * resizing (if any), and (c) whether or not the window is - * gridded. Don't permit sizes <= 0 because this upsets - * the X server. + * resizing (if any), (c) whether or not the window is + * gridded, and (d) the current min or max size for + * the toplevel. Don't permit sizes <= 0 because this + * upsets the X server. */ if (wmPtr->width == -1) { @@ -3982,6 +3986,28 @@ UpdateGeometryInfo(clientData) if (width <= 0) { width = 1; } + /* + * Account for window max/min width + */ + if (wmPtr->gridWin != NULL) { + min = winPtr->reqWidth + + (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; + if (wmPtr->maxWidth > 0) { + max = winPtr->reqWidth + + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; + } else { + max = 0; + } + } else { + min = wmPtr->minWidth; + max = wmPtr->maxWidth; + } + if (width < min) { + width = min; + } else if ((max > 0) && (width > max)) { + width = max; + } + if (wmPtr->height == -1) { height = winPtr->reqHeight; } else if (wmPtr->gridWin != NULL) { @@ -3993,6 +4019,27 @@ UpdateGeometryInfo(clientData) if (height <= 0) { height = 1; } + /* + * Account for window max/min height + */ + if (wmPtr->gridWin != NULL) { + min = winPtr->reqHeight + + (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; + if (wmPtr->maxHeight > 0) { + max = winPtr->reqHeight + + (wmPtr->maxHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; + } else { + max = 0; + } + } else { + min = wmPtr->minHeight; + max = wmPtr->maxHeight; + } + if (height < min) { + height = min; + } else if ((max > 0) && (height > max)) { + height = max; + } /* * Compute the new position for the upper-left pixel of the window's @@ -4029,7 +4076,7 @@ UpdateGeometryInfo(clientData) wmPtr->flags |= WM_UPDATE_SIZE_HINTS; } if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) { - UpdateSizeHints(winPtr); + UpdateSizeHints(winPtr, width, height); } /* @@ -4163,8 +4210,10 @@ UpdateGeometryInfo(clientData) */ static void -UpdateSizeHints(winPtr) +UpdateSizeHints(winPtr, newWidth, newHeight) TkWindow *winPtr; + int newWidth; + int newHeight; { register WmInfo *wmPtr = winPtr->wmInfoPtr; XSizeHints *hintsPtr; @@ -4226,20 +4275,11 @@ UpdateSizeHints(winPtr) */ if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - if (wmPtr->width >= 0) { - hintsPtr->min_width = wmPtr->width; - } else { - hintsPtr->min_width = winPtr->reqWidth; - } - hintsPtr->max_width = hintsPtr->min_width; + hintsPtr->max_width = hintsPtr->min_width = newWidth; } if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - if (wmPtr->height >= 0) { - hintsPtr->min_height = wmPtr->height; - } else { - hintsPtr->min_height = winPtr->reqHeight + wmPtr->menuHeight; - } - hintsPtr->max_height = hintsPtr->min_height; + hintsPtr->max_height = hintsPtr->min_height = + newHeight + wmPtr->menuHeight; } XSetWMNormalHints(winPtr->display, wmPtr->wrapperPtr->window, hintsPtr); diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 69a4bd5..edd91a2 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.54 2002/12/06 23:29:37 hobbs Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.55 2003/03/12 00:25:42 mdejong Exp $ */ #include "tkWinInt.h" @@ -176,9 +176,9 @@ typedef struct TkWmInfo { * window is gridded; otherwise it isn't * gridded. */ int minWidth, minHeight; /* Minimum dimensions of window, in - * grid units, not pixels. */ + * pixels or grid units. */ int maxWidth, maxHeight; /* Maximum dimensions of window, in - * grid units, not pixels, or 0 to default. */ + * pixels or grid units. 0 to default. */ Tk_Window gridWin; /* Identifies the window that controls * gridding for this top-level, or NULL if * the top-level isn't currently gridded. */ @@ -199,7 +199,7 @@ typedef struct TkWmInfo { */ int width, height; /* Desired dimensions of window, specified - * in grid units. These values are + * in pixels or grid units. These values are * set by the "wm geometry" command and by * ConfigureNotify events (for when wm * resizes window). -1 means user hasn't @@ -5018,6 +5018,7 @@ UpdateGeometryInfo(clientData) { int x, y; /* Position of border on desktop. */ int width, height; /* Size of client area. */ + int min, max; RECT rect; register TkWindow *winPtr = (TkWindow *) clientData; register WmInfo *wmPtr = winPtr->wmInfoPtr; @@ -5056,8 +5057,9 @@ UpdateGeometryInfo(clientData) * requested depends on (a) the size requested internally * by the window's widgets, (b) the size requested by the * user in a "wm geometry" command or via wm-based interactive - * resizing (if any), and (c) whether or not the window is - * gridded. Don't permit sizes <= 0 because this upsets + * resizing (if any), (c) whether or not the window is + * gridded, and (d) the current min or max size for + * the toplevel. Don't permit sizes <= 0 because this upsets * the X server. */ @@ -5072,6 +5074,28 @@ UpdateGeometryInfo(clientData) if (width <= 0) { width = 1; } + /* + * Account for window max/min width + */ + if (wmPtr->gridWin != NULL) { + min = winPtr->reqWidth + + (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; + if (wmPtr->maxWidth > 0) { + max = winPtr->reqWidth + + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; + } else { + max = 0; + } + } else { + min = wmPtr->minWidth; + max = wmPtr->maxWidth; + } + if (width < min) { + width = min; + } else if ((max > 0) && (width > max)) { + width = max; + } + if (wmPtr->height == -1) { height = winPtr->reqHeight; } else if (wmPtr->gridWin != NULL) { @@ -5083,6 +5107,27 @@ UpdateGeometryInfo(clientData) if (height <= 0) { height = 1; } + /* + * Account for window max/min height + */ + if (wmPtr->gridWin != NULL) { + min = winPtr->reqHeight + + (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; + if (wmPtr->maxHeight > 0) { + max = winPtr->reqHeight + + (wmPtr->maxHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; + } else { + max = 0; + } + } else { + min = wmPtr->minHeight; + max = wmPtr->maxHeight; + } + if (height < min) { + height = min; + } else if ((max > 0) && (height > max)) { + height = max; + } /* * Compute the new position for the upper-left pixel of the window's |