diff options
author | pspjuth <peter.spjuth@gmail.com> | 2009-08-19 23:01:59 (GMT) |
---|---|---|
committer | pspjuth <peter.spjuth@gmail.com> | 2009-08-19 23:01:59 (GMT) |
commit | 2b61fda7660e28461b6dfe55f422c70aa390483d (patch) | |
tree | a4c7c1cd7c558900a4ca247babd4096d872f1f42 /generic | |
parent | f4cf4a95f73b53ac9c0a6e3c93d9676d2877598e (diff) | |
download | tk-2b61fda7660e28461b6dfe55f422c70aa390483d.zip tk-2b61fda7660e28461b6dfe55f422c70aa390483d.tar.gz tk-2b61fda7660e28461b6dfe55f422c70aa390483d.tar.bz2 |
Give an error if grid and pack are used in the same master. [Patch 2475855]
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tk.h | 3 | ||||
-rw-r--r-- | generic/tkGeometry.c | 81 | ||||
-rw-r--r-- | generic/tkGrid.c | 49 | ||||
-rw-r--r-- | generic/tkInt.h | 8 | ||||
-rw-r--r-- | generic/tkPack.c | 49 | ||||
-rw-r--r-- | generic/tkWindow.c | 7 |
6 files changed, 191 insertions, 6 deletions
diff --git a/generic/tk.h b/generic/tk.h index 0ebd36b..167da5a 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -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: tk.h,v 1.130 2009/06/29 14:35:01 das Exp $ + * RCS: @(#) $Id: tk.h,v 1.131 2009/08/19 23:02:00 pspjuth Exp $ */ #ifndef _TK @@ -791,6 +791,7 @@ typedef struct Tk_FakeWin { int internalBorderBottom; int minReqWidth; int minReqHeight; + char *dummy20; /* geometryMaster */ } Tk_FakeWin; /* diff --git a/generic/tkGeometry.c b/generic/tkGeometry.c index 53bd140..b5a1654 100644 --- a/generic/tkGeometry.c +++ b/generic/tkGeometry.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGeometry.c,v 1.14 2008/11/08 18:44:40 dkf Exp $ + * RCS: @(#) $Id: tkGeometry.c,v 1.15 2009/08/19 23:02:00 pspjuth Exp $ */ #include "tkInt.h" @@ -306,6 +306,85 @@ Tk_SetMinimumRequestSize( /* *---------------------------------------------------------------------- * + * TkSetGeometryMaster -- + * + * Set a geometry master for this window. Only one master may own + * a window at any time. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * The geometry master is recorded for the window. + * + *---------------------------------------------------------------------- + */ + +int +TkSetGeometryMaster( + Tcl_Interp *interp, /* Current interpreter, for error. */ + Tk_Window tkwin, /* Window that will have geometry master set. */ + const char *master) /* The master identity. */ +{ + register TkWindow *winPtr = (TkWindow *) tkwin; + + if (winPtr->geometryMaster != NULL && + strcmp(winPtr->geometryMaster, master) == 0) { + return TCL_OK; + } + if (winPtr->geometryMaster != NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "cannot use geometry manager ", master, + " inside ", Tk_PathName(tkwin), + " which already has slaves managed by ", + winPtr->geometryMaster, NULL); + } + return TCL_ERROR; + } + + winPtr->geometryMaster = ckalloc(strlen(master) + 1); + strcpy(winPtr->geometryMaster, master); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TkFreeGeometryMaster -- + * + * Remove a geometry master for this window. Only one master may own + * a window at any time. + * + * Results: + * None. + * + * Side effects: + * The geometry master is cleared for the window. + * + *---------------------------------------------------------------------- + */ + +void +TkFreeGeometryMaster( + Tk_Window tkwin, /* Window that will have geometry master cleared. */ + const char *master) /* The master identity. */ +{ + register TkWindow *winPtr = (TkWindow *) tkwin; + + if (winPtr->geometryMaster != NULL && + strcmp(winPtr->geometryMaster, master) != 0) { + Tcl_Panic("Trying to free %s from geometry manager %s.", + winPtr->geometryMaster, master); + } + if (winPtr->geometryMaster != NULL) { + ckfree(winPtr->geometryMaster); + winPtr->geometryMaster = NULL; + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_MaintainGeometry -- * * This procedure is invoked by geometry managers to handle slaves whose diff --git a/generic/tkGrid.c b/generic/tkGrid.c index b4392f3..6dbe9a3 100644 --- a/generic/tkGrid.c +++ b/generic/tkGrid.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGrid.c,v 1.52 2009/02/03 23:55:47 nijtmans Exp $ + * RCS: @(#) $Id: tkGrid.c,v 1.53 2009/08/19 23:02:00 pspjuth Exp $ */ #include "tkInt.h" @@ -242,10 +242,13 @@ typedef struct UniformGroup { * size. 0 means if this window is a master then * Tk will set its requested size to fit the * needs of its slaves. + * ALLOCED_MASTER 1 means that Grid has allocated itself as + * geometry master for this window. */ #define REQUESTED_RELAYOUT 1 #define DONT_PROPAGATE 2 +#define ALLOCED_MASTER 4 /* * Prototypes for procedures used only in this file: @@ -875,8 +878,22 @@ GridPropagateCommand( old = !(masterPtr->flags & DONT_PROPAGATE); if (propagate != old) { if (propagate) { + /* + * If we have slaves, we need to register as geometry master. + */ + + if (masterPtr->slavePtr != NULL) { + if (TkSetGeometryMaster(interp, master, "grid") != TCL_OK) { + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } masterPtr->flags &= ~DONT_PROPAGATE; } else { + if (masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(master, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } masterPtr->flags |= DONT_PROPAGATE; } @@ -2724,6 +2741,16 @@ Unlink( SetGridSize(slavePtr->masterPtr); slavePtr->masterPtr = NULL; + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { + TkFreeGeometryMaster(masterPtr->tkwin, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } } /* @@ -3262,6 +3289,15 @@ ConfigureSlaves( Tk_ManageGeometry(slave, &gridMgrType, slavePtr); + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "grid") + != TCL_OK) { + Tk_ManageGeometry(slave, NULL, NULL); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } + /* * Assign default position information. */ @@ -3386,6 +3422,17 @@ ConfigureSlaves( return TCL_ERROR; } SetGridSize(masterPtr); + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(masterPtr->tkwin, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } + return TCL_OK; } diff --git a/generic/tkInt.h b/generic/tkInt.h index 430d51e..958695e 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: $Id: tkInt.h,v 1.106 2009/07/02 10:34:32 patthoyts Exp $ + * RCS: $Id: tkInt.h,v 1.107 2009/08/19 23:02:00 pspjuth Exp $ */ #ifndef _TKINT @@ -851,6 +851,7 @@ typedef struct TkWindow { int minReqWidth; /* Minimum requested width. */ int minReqHeight; /* Minimum requested height. */ + char *geometryMaster; } TkWindow; /* @@ -1164,6 +1165,11 @@ MODULE_SCOPE int Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp, MODULE_SCOPE int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); +MODULE_SCOPE int TkSetGeometryMaster(Tcl_Interp *interp, + Tk_Window tkwin, const char *master); +MODULE_SCOPE void TkFreeGeometryMaster(Tk_Window tkwin, + const char *master); + MODULE_SCOPE void TkEventInit(void); MODULE_SCOPE void TkRegisterObjTypes(void); MODULE_SCOPE int TkCreateMenuCmd(Tcl_Interp *interp); diff --git a/generic/tkPack.c b/generic/tkPack.c index 334afdb..c113e6f 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkPack.c,v 1.33 2009/02/03 23:55:47 nijtmans Exp $ + * RCS: @(#) $Id: tkPack.c,v 1.34 2009/08/19 23:02:00 pspjuth Exp $ */ #include "tkInt.h" @@ -89,6 +89,8 @@ typedef struct Packer { * size. 0 means if this window is a master then * Tk will set its requested size to fit the * needs of its slaves. + * ALLOCED_MASTER 1 means that Pack has allocated itself as + * geometry master for this window. */ #define REQUESTED_REPACK 1 @@ -97,6 +99,7 @@ typedef struct Packer { #define EXPAND 8 #define OLD_STYLE 16 #define DONT_PROPAGATE 32 +#define ALLOCED_MASTER 64 /* * The following structure is the official type record for the packer: @@ -385,6 +388,16 @@ Tk_PackObjCmd( return TCL_ERROR; } if (propagate) { + /* + * If we have slaves, we need to register as geometry master. + */ + + if (masterPtr->slavePtr != NULL) { + if (TkSetGeometryMaster(interp, master, "pack") != TCL_OK) { + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } masterPtr->flags &= ~DONT_PROPAGATE; /* @@ -400,6 +413,10 @@ Tk_PackObjCmd( Tcl_DoWhenIdle(ArrangePacking, masterPtr); } } else { + if (masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(master, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } masterPtr->flags |= DONT_PROPAGATE; } break; @@ -1239,6 +1256,15 @@ PackAfter( prevPtr->nextPtr = packPtr; } Tk_ManageGeometry(tkwin, &packerType, packPtr); + + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(tkwin, NULL, NULL); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } } } @@ -1304,6 +1330,17 @@ Unlink( } packPtr->masterPtr = NULL; + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(masterPtr->tkwin, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } + } /* @@ -1740,6 +1777,7 @@ ConfigureSlaves( } Unlink(slavePtr); } + slavePtr->masterPtr = masterPtr; if (prevPtr == NULL) { slavePtr->nextPtr = masterPtr->slavePtr; @@ -1751,6 +1789,15 @@ ConfigureSlaves( Tk_ManageGeometry(slave, &packerType, slavePtr); prevPtr = slavePtr; + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(slave, NULL, NULL); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } + /* * Arrange for the master to be re-packed at the first idle moment. */ diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 8c2d435..70c8472 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWindow.c,v 1.103 2009/02/27 23:04:39 patthoyts Exp $ + * RCS: @(#) $Id: tkWindow.c,v 1.104 2009/08/19 23:02:00 pspjuth Exp $ */ #include "tkInt.h" @@ -709,6 +709,7 @@ TkAllocWindow( winPtr->internalBorderBottom = 0; winPtr->minReqWidth = 0; winPtr->minReqHeight = 0; + winPtr->geometryMaster = NULL; return winPtr; } @@ -1485,6 +1486,10 @@ Tk_DestroyWindow( TkOptionDeadWindow(winPtr); TkSelDeadWindow(winPtr); TkGrabDeadWindow(winPtr); + if (winPtr->geometryMaster != NULL) { + ckfree(winPtr->geometryMaster); + winPtr->geometryMaster = NULL; + } if (winPtr->mainPtr != NULL) { if (winPtr->pathName != NULL) { Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable, |