summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormdejong <mdejong>2003-03-12 00:09:32 (GMT)
committermdejong <mdejong>2003-03-12 00:09:32 (GMT)
commit6be1cd95fff709a3869038db3e989865154259fb (patch)
treeecef370c50b2d02b66d81ba8deaa5e9601199442
parent7be603f3c85d34e87e54b45c813ecbe337c89854 (diff)
downloadtk-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]
-rw-r--r--ChangeLog39
-rw-r--r--generic/tkGrid.c75
-rw-r--r--generic/tkPack.c43
-rw-r--r--generic/tkPlace.c119
-rw-r--r--tests/grid.test10
-rw-r--r--tests/pack.test8
-rw-r--r--tests/place.test8
7 files changed, 203 insertions, 99 deletions
diff --git a/ChangeLog b/ChangeLog
index 7537547..dac42f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+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
+ 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]
+
2002-03-11 Kevin Kenny <kennykb@users.sourceforge.net>
* win/makefile.vc: Backported the code that makes the makefile
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index f5c3503..78fe219 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.25 2002/10/10 21:07:51 pspjuth Exp $
+ * RCS: @(#) $Id: tkGrid.c,v 1.26 2003/03/12 00:09:36 mdejong Exp $
*/
#include "tkInt.h"
@@ -141,9 +141,9 @@ typedef struct {
int rowSpace; /* The number of slots currently allocated
* for row constraints. */
int startX; /* Pixel offset of this layout within its
- * parent. */
+ * master. */
int startY; /* Pixel offset of this layout within its
- * parent. */
+ * master. */
} GridMaster;
/*
@@ -163,7 +163,7 @@ typedef struct Gridder {
* is managed (NULL means this window
* isn't managed by the gridder). */
struct Gridder *nextPtr; /* Next window managed within same
- * parent. List order doesn't matter. */
+ * master. List order doesn't matter. */
struct Gridder *slavePtr; /* First in list of slaves managed
* inside this window (NULL means
* no grid slaves). */
@@ -187,7 +187,7 @@ typedef struct Gridder {
* sticks to. See below for definitions */
int doubleBw; /* Twice the window's last known border
* width. If this changes, the window
- * must be re-arranged within its parent. */
+ * must be re-arranged within its master. */
int *abortPtr; /* If non-NULL, it means that there is a nested
* call to ArrangeGrid already working on
* this window. *abortPtr may be set to 1 to
@@ -676,7 +676,7 @@ GridLocationCommand(tkwin, interp, objc, objv)
Gridder *masterPtr; /* master grid record */
GridMaster *gridPtr; /* pointer to grid data */
register SlotInfo *slotPtr;
- int x, y; /* Offset in pixels, from edge of parent. */
+ int x, y; /* Offset in pixels, from edge of master. */
int i, j; /* Corresponding column and row indeces. */
int endX, endY; /* end of grid */
@@ -1286,7 +1286,7 @@ AdjustOffsets(size, slots, slotPtr)
}
/*
- * If all the weights are zero, center the layout in its parent if
+ * If all the weights are zero, center the layout in its master if
* there is extra space, else clip on the bottom/right.
*/
@@ -1487,7 +1487,7 @@ AdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr)
static void
ArrangeGrid(clientData)
- ClientData clientData; /* Structure describing parent whose slaves
+ ClientData clientData; /* Structure describing master whose slaves
* are to be re-layed out. */
{
register Gridder *masterPtr = (Gridder *) clientData;
@@ -1500,9 +1500,9 @@ ArrangeGrid(clientData)
masterPtr->flags &= ~REQUESTED_RELAYOUT;
/*
- * If the parent has no slaves anymore, then don't do anything
- * at all: just leave the parent's size as-is. Otherwise there is
- * no way to "relinquish" control over the parent so another geometry
+ * If the master has no slaves anymore, then don't do anything
+ * at all: just leave the master's size as-is. Otherwise there is
+ * no way to "relinquish" control over the master so another geometry
* manager can take over.
*/
@@ -1560,10 +1560,10 @@ ArrangeGrid(clientData)
}
/*
- * If the currently requested layout size doesn't match the parent's
+ * If the currently requested layout size doesn't match the master's
* window size, then adjust the slot offsets according to the
* weights. If all of the weights are zero, center the layout in
- * its parent. I haven't decided what to do if the parent is smaller
+ * its master. I haven't decided what to do if the master is smaller
* than the requested size.
*/
@@ -2325,13 +2325,13 @@ InitMasterData(masterPtr)
*
* Unlink --
*
- * Remove a grid from its parent's list of slaves.
+ * Remove a grid from its master's list of slaves.
*
* Results:
* None.
*
* Side effects:
- * The parent will be scheduled for re-arranging, and the size of the
+ * The master will be scheduled for re-arranging, and the size of the
* grid will be adjusted accordingly
*
*----------------------------------------------------------------------
@@ -2440,13 +2440,14 @@ GridStructureProc(clientData, eventPtr)
TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr;
if (eventPtr->type == ConfigureNotify) {
- if (!(gridPtr->flags & REQUESTED_RELAYOUT)) {
+ if ((gridPtr->slavePtr != NULL)
+ && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
}
- if (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width) {
- if ((gridPtr->masterPtr != NULL) &&
- !(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
+ if ((gridPtr->masterPtr != NULL)
+ && (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) {
+ if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width;
gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr->masterPtr);
@@ -2473,7 +2474,8 @@ GridStructureProc(clientData, eventPtr)
gridPtr->tkwin = NULL;
Tcl_EventuallyFree((ClientData) gridPtr, DestroyGrid);
} else if (eventPtr->type == MapNotify) {
- if (!(gridPtr->flags & REQUESTED_RELAYOUT)) {
+ if ((gridPtr->slavePtr != NULL)
+ && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
}
@@ -2542,6 +2544,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
int index;
char *string;
char firstChar, prevChar;
+ int positionGiven;
/*
* Count the number of windows, or window short-cuts.
@@ -2609,6 +2612,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
*/
masterPtr = NULL;
+ positionGiven = 0;
for (j = 0; j < numWindows; j++) {
string = Tcl_GetString(objv[j]);
firstChar = string[0];
@@ -2695,6 +2699,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
TCL_STATIC);
return TCL_ERROR;
}
+ positionGiven = 1;
masterPtr = GetGrid(other);
InitMasterData(masterPtr);
} else if (index == CONF_IPADX) {
@@ -2765,15 +2770,30 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
/*
- * Make sure we have a geometry master. We look at:
- * 1) the -in flag
- * 2) the geometry master of the first slave (if specified)
- * 3) the parent of the first slave.
+ * If no position was specified via -in and the slave is
+ * already packed, then leave it in its current location.
*/
-
- if (masterPtr == NULL) {
+
+ if (!positionGiven && (slavePtr->masterPtr != NULL)) {
masterPtr = slavePtr->masterPtr;
+ goto scheduleLayout;
}
+
+ /*
+ * If the same -in window is passed in again, then just
+ * leave it in its current location.
+ */
+
+ if (positionGiven && (masterPtr == slavePtr->masterPtr)) {
+ goto scheduleLayout;
+ }
+
+ /*
+ * Make sure we have a geometry master. We look at:
+ * 1) the -in flag
+ * 2) the parent of the first slave.
+ */
+
parent = Tk_Parent(slave);
if (masterPtr == NULL) {
masterPtr = GetGrid(parent);
@@ -2845,10 +2865,11 @@ ConfigureSlaves(interp, tkwin, objc, objv)
defaultColumnSpan = 1;
/*
- * Arrange for the parent to be re-arranged at the first
+ * Arrange for the master to be re-arranged at the first
* idle moment.
*/
+ scheduleLayout:
if (masterPtr->abortPtr != NULL) {
*masterPtr->abortPtr = 1;
}
diff --git a/generic/tkPack.c b/generic/tkPack.c
index 607af25..cdb52be 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.16 2002/06/14 22:25:12 jenglish Exp $
+ * RCS: @(#) $Id: tkPack.c,v 1.17 2003/03/12 00:09:36 mdejong Exp $
*/
#include "tkPort.h"
@@ -37,12 +37,12 @@ typedef struct Packer {
* is packed (NULL means this window
* isn't managed by the packer). */
struct Packer *nextPtr; /* Next window packed within same
- * parent. List is priority-ordered:
+ * master. List is priority-ordered:
* first on list gets packed first. */
struct Packer *slavePtr; /* First in list of slaves packed
* inside this window (NULL means
* no packed slaves). */
- Side side; /* Side of parent against which
+ Side side; /* Side of master against which
* this window is packed. */
Tk_Anchor anchor; /* If frame allocated for window is larger
* than window needs, this indicates how
@@ -60,7 +60,7 @@ typedef struct Packer {
* each side). */
int doubleBw; /* Twice the window's last known border
* width. If this changes, the window
- * must be repacked within its parent. */
+ * must be repacked within its master. */
int *abortPtr; /* If non-NULL, it means that there is a nested
* call to ArrangePacking already working on
* this window. *abortPtr may be set to 1 to
@@ -83,7 +83,7 @@ typedef struct Packer {
* any larger than needed.
* FILLY: Same as FILLX, except for height.
* EXPAND: 1 means this window's frame will absorb any
- * extra space in the parent window.
+ * extra space in the master window.
* OLD_STYLE: 1 means this window is being managed with
* the old-style packer algorithms (before
* Tk version 3.3). The main difference is
@@ -544,7 +544,7 @@ PackLostSlaveProc(clientData, tkwin)
static void
ArrangePacking(clientData)
- ClientData clientData; /* Structure describing parent whose slaves
+ ClientData clientData; /* Structure describing master whose slaves
* are to be re-layed out. */
{
register Packer *masterPtr = (Packer *) clientData;
@@ -552,7 +552,7 @@ ArrangePacking(clientData)
int cavityX, cavityY, cavityWidth, cavityHeight;
/* These variables keep track of the
* as-yet-unallocated space remaining in
- * the middle of the parent window. */
+ * the middle of the master window. */
int frameX, frameY, frameWidth, frameHeight;
/* These variables keep track of the frame
* allocated to the current window. */
@@ -568,8 +568,8 @@ ArrangePacking(clientData)
masterPtr->flags &= ~REQUESTED_REPACK;
/*
- * If the parent has no slaves anymore, then don't do anything
- * at all: just leave the parent's size as-is.
+ * If the master has no slaves anymore, then don't do anything
+ * at all: just leave the master's size as-is.
*/
if (masterPtr->slavePtr == NULL) {
@@ -648,10 +648,10 @@ ArrangePacking(clientData)
}
/*
- * If the total amount of space needed in the parent window has
+ * If the total amount of space needed in the master window has
* changed, and if we're propagating geometry information, then
* notify the next geometry manager up and requeue ourselves to
- * start again after the parent has had a chance to
+ * start again after the master has had a chance to
* resize us.
*/
@@ -1129,7 +1129,7 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
* PackAfter --
*
* This procedure does most of the real work of adding
- * one or more windows into the packing order for its parent.
+ * one or more windows into the packing order for its master.
*
* Results:
* A standard Tcl return value.
@@ -1316,7 +1316,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
}
/*
- * Add the window in the correct place in its parent's
+ * Add the window in the correct place in its master's
* packing order, then make sure that the window is
* managed by us.
*/
@@ -1334,7 +1334,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
}
/*
- * Arrange for the parent to be re-packed at the first
+ * Arrange for the master to be re-packed at the first
* idle moment.
*/
@@ -1353,13 +1353,13 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
*
* Unlink --
*
- * Remove a packer from its parent's list of slaves.
+ * Remove a packer from its master's list of slaves.
*
* Results:
* None.
*
* Side effects:
- * The parent will be scheduled for repacking.
+ * The master will be scheduled for repacking.
*
*----------------------------------------------------------------------
*/
@@ -1458,9 +1458,9 @@ PackStructureProc(clientData, eventPtr)
packPtr->flags |= REQUESTED_REPACK;
Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr);
}
- if (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width) {
- if ((packPtr->masterPtr != NULL)
- && !(packPtr->masterPtr->flags & REQUESTED_REPACK)) {
+ if ((packPtr->masterPtr != NULL)
+ && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) {
+ if (!(packPtr->masterPtr->flags & REQUESTED_REPACK)) {
packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width;
packPtr->masterPtr->flags |= REQUESTED_REPACK;
Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr->masterPtr);
@@ -1759,7 +1759,8 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
/*
- * If the slave is going to be put back after itself then
+ * If the slave is going to be put back after itself or
+ * the same -in window is passed in again, then just
* skip the whole operation, since it won't work anyway.
*/
@@ -1834,7 +1835,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
prevPtr = slavePtr;
/*
- * Arrange for the parent to be re-packed at the first
+ * Arrange for the master to be re-packed at the first
* idle moment.
*/
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);
diff --git a/tests/grid.test b/tests/grid.test
index c47348e..47f99c0 100644
--- a/tests/grid.test
+++ b/tests/grid.test
@@ -5,7 +5,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: grid.test,v 1.17 2002/10/10 21:07:52 pspjuth Exp $
+# RCS: @(#) $Id: grid.test,v 1.18 2003/03/12 00:09:37 mdejong Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -946,6 +946,14 @@ test grid-13.1 {-in} {
} {1 {Window can't be managed in itself}}
grid_reset 13.1
+test grid-13.1.1 {-in} {
+ frame .f -bg red
+ list [winfo manager .f] \
+ [catch {grid .f -in .f} err] $err \
+ [winfo manager .f]
+} {{} 1 {Window can't be managed in itself} {}}
+grid_reset 13.1.1
+
test grid-13.2 {-in} {
frame .f -bg red
list [catch "grid .f -in .bad" msg] $msg
diff --git a/tests/pack.test b/tests/pack.test
index 488281a..c4af29f 100644
--- a/tests/pack.test
+++ b/tests/pack.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: pack.test,v 1.10 2002/07/13 20:28:35 dgp Exp $
+# RCS: @(#) $Id: pack.test,v 1.11 2003/03/12 00:09:40 mdejong Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -615,6 +615,12 @@ test pack-10.2 {retaining/clearing configuration state} {
pack .pack.a -pady 14
pack info .pack.a
} {-in .pack -anchor n -expand 1 -fill both -ipadx 3 -ipady 4 -padx 1 -pady 14 -side bottom}
+test pack-10.3 {bad -in window does not change master} {
+ pack forget .pack.a .pack.b .pack.c .pack.d
+ list [winfo manager .pack.a] \
+ [catch {pack .pack.a -in .pack.a} err] $err \
+ [winfo manager .pack.a]
+} {{} 1 {can't pack .pack.a inside itself} {}}
test pack-11.1 {info option} {
pack4 -in .pack
diff --git a/tests/place.test b/tests/place.test
index 4bf47fb..10e45b7 100644
--- a/tests/place.test
+++ b/tests/place.test
@@ -5,7 +5,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: place.test,v 1.8 2002/11/07 19:10:30 pspjuth Exp $
+# RCS: @(#) $Id: place.test,v 1.9 2003/03/12 00:09:40 mdejong Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -87,6 +87,12 @@ test place-4.1 {ConfigureSlave procedure, bad -in options} {
} [list 1 "can't place .t.f2 relative to itself"]
test place-4.2 {ConfigureSlave procedure, bad -in option} {
place forget .t.f2
+ list [winfo manager .t.f2] \
+ [catch {place .t.f2 -in .t.f2} err] $err \
+ [winfo manager .t.f2]
+} {{} 1 {can't place .t.f2 relative to itself} {}}
+test place-4.3 {ConfigureSlave procedure, bad -in option} {
+ place forget .t.f2
list [catch {place .t.f2 -in .} msg] $msg
} [list 1 "can't place .t.f2 relative to ."]