diff options
author | mdejong <mdejong> | 2003-03-12 00:09:32 (GMT) |
---|---|---|
committer | mdejong <mdejong> | 2003-03-12 00:09:32 (GMT) |
commit | 6be1cd95fff709a3869038db3e989865154259fb (patch) | |
tree | ecef370c50b2d02b66d81ba8deaa5e9601199442 /generic/tkPlace.c | |
parent | 7be603f3c85d34e87e54b45c813ecbe337c89854 (diff) | |
download | tk-6be1cd95fff709a3869038db3e989865154259fb.zip tk-6be1cd95fff709a3869038db3e989865154259fb.tar.gz tk-6be1cd95fff709a3869038db3e989865154259fb.tar.bz2 |
* generic/tkGrid.c (GridStructureProc, ConfigureSlaves):
Check for a NULL masterPtr and slavePtr in the
GridStructureProc code to ensure that a Gridder
created before some error condition is ignored
when it comes to geometry calculations. This
approach closely matches the pack implementation.
Keep track of a -in argument to a grid command
in order to detect the case of an already
gridded widget that wants to change some options.
The previous implementation could make repeated
and unnecessary calls to Tk_ManageGeometry.
Replace use of "parent" with "master" in comments
throughout the file.
* generic/tkPack.c (PackStructureProc): Check for
a NULL masterPtr before other checks so that a
slave created under certain error conditions
is cleaned up properly.
Replace use of "parent" with "master" in comments
throughout the file.
* generic/tkPlace.c (CreateSlave, ConfigureSlave,
SlaveStructureProc):
Don't call Tk_ManageGeometry in CreateSlave since
this was causing incorrect results in some error
cases. Rework the ConfigureSlave method so that
slave setup is done in one place. The call to
Tk_ManageGeometry was added to the one place
where a slave is setup. When a slave is configured
but the master is not changed, simply goto the
scheduleLayout label. Check for a NULL master
in SlaveStructureProc for the sake of readability.
* tests/grid.test:
* tests/pack.test:
* tests/place.test: Add test to check that a
winfo manager call does not return incorrect
results after an error condition is hit.
[Patch 693063]
Diffstat (limited to 'generic/tkPlace.c')
-rw-r--r-- | generic/tkPlace.c | 119 |
1 files changed, 71 insertions, 48 deletions
diff --git a/generic/tkPlace.c b/generic/tkPlace.c index 05a75fb..09452b3 100644 --- a/generic/tkPlace.c +++ b/generic/tkPlace.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: tkPlace.c,v 1.13 2002/11/07 19:10:30 pspjuth Exp $ + * RCS: @(#) $Id: tkPlace.c,v 1.14 2003/03/12 00:09:37 mdejong Exp $ */ #include "tkPort.h" @@ -398,7 +398,6 @@ CreateSlave(tkwin) Tcl_SetHashValue(hPtr, slavePtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, (ClientData) slavePtr); - Tk_ManageGeometry(tkwin, &placerType, (ClientData) slavePtr); } else { slavePtr = (Slave *) Tcl_GetHashValue(hPtr); } @@ -590,9 +589,9 @@ ConfigureSlave(interp, tkwin, table, objc, objv) register Master *masterPtr; Tk_SavedOptions savedOptions; int mask; - int result = TCL_OK; Slave *slavePtr; - + Tk_Window masterWin = (Tk_Window) NULL; + if (Tk_TopWinHierarchy(tkwin)) { Tcl_AppendResult(interp, "can't use placer on top-level window \"", Tk_PathName(tkwin), "\"; use wm command instead", @@ -601,27 +600,54 @@ ConfigureSlave(interp, tkwin, table, objc, objv) } slavePtr = CreateSlave(tkwin); - + if (Tk_SetOptions(interp, (char *)slavePtr, table, objc, objv, slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) { - Tk_RestoreSavedOptions(&savedOptions); - result = TCL_ERROR; - goto done; + goto error; + } + + /* + * Set slave flags. First clear the field, then add bits as needed. + */ + + slavePtr->flags = 0; + if (slavePtr->heightPtr) { + slavePtr->flags |= CHILD_HEIGHT; + } + + if (slavePtr->relHeightPtr) { + slavePtr->flags |= CHILD_REL_HEIGHT; + } + + if (slavePtr->relWidthPtr) { + slavePtr->flags |= CHILD_REL_WIDTH; + } + + if (slavePtr->widthPtr) { + slavePtr->flags |= CHILD_WIDTH; } - if (mask & IN_MASK) { + if (((mask & IN_MASK) == 0) && (slavePtr->masterPtr != NULL)) { + /* + * If no -in option was passed and the slave is already placed + * then just recompute the placement. + */ + + masterPtr = slavePtr->masterPtr; + goto scheduleLayout; + } else if (mask & IN_MASK) { /* -in changed */ Tk_Window tkwin; Tk_Window ancestor; - + tkwin = slavePtr->inTkwin; - + /* * Make sure that the new master is either the logical parent * of the slave or a descendant of that window, and that the * master and slave aren't the same. */ - + for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == Tk_Parent(slavePtr->tkwin)) { break; @@ -630,24 +656,22 @@ ConfigureSlave(interp, tkwin, table, objc, objv) Tcl_AppendResult(interp, "can't place ", Tk_PathName(slavePtr->tkwin), " relative to ", Tk_PathName(tkwin), (char *) NULL); - result = TCL_ERROR; - Tk_RestoreSavedOptions(&savedOptions); - goto done; + goto error; } } if (slavePtr->tkwin == tkwin) { Tcl_AppendResult(interp, "can't place ", Tk_PathName(slavePtr->tkwin), " relative to itself", (char *) NULL); - result = TCL_ERROR; - Tk_RestoreSavedOptions(&savedOptions); - goto done; + goto error; } if ((slavePtr->masterPtr != NULL) && (slavePtr->masterPtr->tkwin == tkwin)) { /* * Re-using same old master. Nothing to do. */ + masterPtr = slavePtr->masterPtr; + goto scheduleLayout; } else { if ((slavePtr->masterPtr != NULL) && (slavePtr->masterPtr->tkwin @@ -656,53 +680,50 @@ ConfigureSlave(interp, tkwin, table, objc, objv) slavePtr->masterPtr->tkwin); } UnlinkSlave(slavePtr); - slavePtr->masterPtr = CreateMaster(tkwin); - slavePtr->nextPtr = slavePtr->masterPtr->slavePtr; - slavePtr->masterPtr->slavePtr = slavePtr; + masterWin = tkwin; } } /* - * Set slave flags. First clear the field, then add bits as needed. + * If there's no master specified for this slave, use its Tk_Parent. */ - slavePtr->flags = 0; - if (slavePtr->heightPtr) { - slavePtr->flags |= CHILD_HEIGHT; + if (masterWin == NULL) { + masterWin = Tk_Parent(slavePtr->tkwin); + slavePtr->inTkwin = masterWin; } - if (slavePtr->relHeightPtr) { - slavePtr->flags |= CHILD_REL_HEIGHT; - } + /* + * Manage the slave window in this master. + */ - if (slavePtr->relWidthPtr) { - slavePtr->flags |= CHILD_REL_WIDTH; - } - - if (slavePtr->widthPtr) { - slavePtr->flags |= CHILD_WIDTH; - } + masterPtr = CreateMaster(masterWin); + slavePtr->masterPtr = masterPtr; + slavePtr->nextPtr = masterPtr->slavePtr; + masterPtr->slavePtr = slavePtr; + Tk_ManageGeometry(slavePtr->tkwin, &placerType, (ClientData) slavePtr); /* - * If there's no master specified for this slave, use its Tk_Parent. - * Then arrange for a placement recalculation in the master. + * Arrange for the master to be re-arranged at the first + * idle moment. */ + scheduleLayout: Tk_FreeSavedOptions(&savedOptions); - done: - masterPtr = slavePtr->masterPtr; - if (masterPtr == NULL) { - masterPtr = CreateMaster(Tk_Parent(slavePtr->tkwin)); - slavePtr->masterPtr = masterPtr; - slavePtr->nextPtr = masterPtr->slavePtr; - masterPtr->slavePtr = slavePtr; - } - slavePtr->inTkwin = masterPtr->tkwin; + if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); } - return result; + return TCL_OK; + + /* + * Error while processing some option, cleanup and return. + */ + + error: + Tk_RestoreSavedOptions(&savedOptions); + return TCL_ERROR; } /* @@ -1074,7 +1095,9 @@ SlaveStructureProc(clientData, eventPtr) TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr; if (eventPtr->type == DestroyNotify) { - UnlinkSlave(slavePtr); + if (slavePtr->masterPtr != NULL) { + UnlinkSlave(slavePtr); + } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) slavePtr->tkwin)); ckfree((char *) slavePtr); |