📄 tkgeometry.c
字号:
slavePtr = slavePtr->nextPtr) { if (slavePtr->slave == slave) { goto gotSlave; } } slavePtr = (MaintainSlave *) ckalloc(sizeof(MaintainSlave)); slavePtr->slave = slave; slavePtr->master = master; slavePtr->nextPtr = masterPtr->slavePtr; masterPtr->slavePtr = slavePtr; Tk_CreateEventHandler(slave, StructureNotifyMask, MaintainSlaveProc, (ClientData) slavePtr); /* * Make sure that there are event handlers registered for all * the windows between master and slave's parent (including master * but not slave's parent). There may already be handlers for master * and some of its ancestors (masterPtr->ancestor tells how many). */ for (ancestor = master; ancestor != parent; ancestor = Tk_Parent(ancestor)) { if (ancestor == masterPtr->ancestor) { Tk_CreateEventHandler(ancestor, StructureNotifyMask, MaintainMasterProc, (ClientData) masterPtr); masterPtr->ancestor = Tk_Parent(ancestor); } } /* * Fill in up-to-date information in the structure, then update the * window if it's not currently in the right place or state. */ gotSlave: slavePtr->x = x; slavePtr->y = y; slavePtr->width = width; slavePtr->height = height; map = 1; for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) { if (!Tk_IsMapped(ancestor) && (ancestor != parent)) { map = 0; } if (ancestor == parent) { if ((x != Tk_X(slavePtr->slave)) || (y != Tk_Y(slavePtr->slave)) || (width != Tk_Width(slavePtr->slave)) || (height != Tk_Height(slavePtr->slave))) { Tk_MoveResizeWindow(slavePtr->slave, x, y, width, height); } if (map) { Tk_MapWindow(slavePtr->slave); } else { Tk_UnmapWindow(slavePtr->slave); } break; } x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width; y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width; }}/* *---------------------------------------------------------------------- * * Tk_UnmaintainGeometry -- * * This procedure cancels a previous Tk_MaintainGeometry call, * so that the relationship between slave and master is no longer * maintained. * * Results: * None. * * Side effects: * The slave is unmapped and state is released, so that slave won't * track master any more. If we weren't previously managing slave * relative to master, then this procedure has no effect. * *---------------------------------------------------------------------- */voidTk_UnmaintainGeometry(slave, master) Tk_Window slave; /* Slave for geometry management. */ Tk_Window master; /* Master for slave; must be a descendant * of slave's parent. */{ Tcl_HashEntry *hPtr; MaintainMaster *masterPtr; register MaintainSlave *slavePtr, *prevPtr; Tk_Window ancestor; if (!initialized) { initialized = 1; Tcl_InitHashTable(&maintainHashTable, TCL_ONE_WORD_KEYS); } if (!(((TkWindow *) slave)->flags & TK_ALREADY_DEAD)) { Tk_UnmapWindow(slave); } hPtr = Tcl_FindHashEntry(&maintainHashTable, (char *) master); if (hPtr == NULL) { return; } masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr); slavePtr = masterPtr->slavePtr; if (slavePtr->slave == slave) { masterPtr->slavePtr = slavePtr->nextPtr; } else { for (prevPtr = slavePtr, slavePtr = slavePtr->nextPtr; ; prevPtr = slavePtr, slavePtr = slavePtr->nextPtr) { if (slavePtr == NULL) { return; } if (slavePtr->slave == slave) { prevPtr->nextPtr = slavePtr->nextPtr; break; } } } Tk_DeleteEventHandler(slavePtr->slave, StructureNotifyMask, MaintainSlaveProc, (ClientData) slavePtr); ckfree((char *) slavePtr); if (masterPtr->slavePtr == NULL) { if (masterPtr->ancestor != NULL) { for (ancestor = master; ; ancestor = Tk_Parent(ancestor)) { Tk_DeleteEventHandler(ancestor, StructureNotifyMask, MaintainMasterProc, (ClientData) masterPtr); if (ancestor == masterPtr->ancestor) { break; } } } if (masterPtr->checkScheduled) { Tcl_CancelIdleCall(MaintainCheckProc, (ClientData) masterPtr); } Tcl_DeleteHashEntry(hPtr); ckfree((char *) masterPtr); }}/* *---------------------------------------------------------------------- * * MaintainMasterProc -- * * This procedure is invoked by the Tk event dispatcher in * response to StructureNotify events on the master or one * of its ancestors, on behalf of Tk_MaintainGeometry. * * Results: * None. * * Side effects: * It schedules a call to MaintainCheckProc, which will eventually * caused the postions and mapped states to be recalculated for all * the maintained slaves of the master. Or, if the master window is * being deleted then state is cleaned up. * *---------------------------------------------------------------------- */static voidMaintainMasterProc(clientData, eventPtr) ClientData clientData; /* Pointer to MaintainMaster structure * for the master window. */ XEvent *eventPtr; /* Describes what just happened. */{ MaintainMaster *masterPtr = (MaintainMaster *) clientData; MaintainSlave *slavePtr; int done; if ((eventPtr->type == ConfigureNotify) || (eventPtr->type == MapNotify) || (eventPtr->type == UnmapNotify)) { if (!masterPtr->checkScheduled) { masterPtr->checkScheduled = 1; Tcl_DoWhenIdle(MaintainCheckProc, (ClientData) masterPtr); } } else if (eventPtr->type == DestroyNotify) { /* * Delete all of the state associated with this master, but * be careful not to use masterPtr after the last slave is * deleted, since its memory will have been freed. */ done = 0; do { slavePtr = masterPtr->slavePtr; if (slavePtr->nextPtr == NULL) { done = 1; } Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master); } while (!done); }}/* *---------------------------------------------------------------------- * * MaintainSlaveProc -- * * This procedure is invoked by the Tk event dispatcher in * response to StructureNotify events on a slave being managed * by Tk_MaintainGeometry. * * Results: * None. * * Side effects: * If the event is a DestroyNotify event then the Maintain state * and event handlers for this slave are deleted. * *---------------------------------------------------------------------- */static voidMaintainSlaveProc(clientData, eventPtr) ClientData clientData; /* Pointer to MaintainSlave structure * for master-slave pair. */ XEvent *eventPtr; /* Describes what just happened. */{ MaintainSlave *slavePtr = (MaintainSlave *) clientData; if (eventPtr->type == DestroyNotify) { Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master); }}/* *---------------------------------------------------------------------- * * MaintainCheckProc -- * * This procedure is invoked by the Tk event dispatcher as an * idle handler, when a master or one of its ancestors has been * reconfigured, mapped, or unmapped. Its job is to scan all of * the slaves for the master and reposition them, map them, or * unmap them as needed to maintain their geometry relative to * the master. * * Results: * None. * * Side effects: * Slaves can get repositioned, mapped, or unmapped. * *---------------------------------------------------------------------- */static voidMaintainCheckProc(clientData) ClientData clientData; /* Pointer to MaintainMaster structure * for the master window. */{ MaintainMaster *masterPtr = (MaintainMaster *) clientData; MaintainSlave *slavePtr; Tk_Window ancestor, parent; int x, y, map; masterPtr->checkScheduled = 0; for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { parent = Tk_Parent(slavePtr->slave); x = slavePtr->x; y = slavePtr->y; map = 1; for (ancestor = slavePtr->master; ; ancestor = Tk_Parent(ancestor)) { if (!Tk_IsMapped(ancestor) && (ancestor != parent)) { map = 0; } if (ancestor == parent) { if ((x != Tk_X(slavePtr->slave)) || (y != Tk_Y(slavePtr->slave))) { Tk_MoveWindow(slavePtr->slave, x, y); } if (map) { Tk_MapWindow(slavePtr->slave); } else { Tk_UnmapWindow(slavePtr->slave); } break; } x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width; y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -