📄 tkmacwm.c
字号:
}}/* *---------------------------------------------------------------------- * * Tk_UnsetGrid -- * * This procedure cancels the effect of a previous call * to Tk_SetGrid. * * Results: * None. * * Side effects: * If tkwin currently controls gridding for its top-level window, * gridding is cancelled for that top-level window; if some other * window controls gridding then this procedure has no effect. * *---------------------------------------------------------------------- */voidTk_UnsetGrid( Tk_Window tkwin) /* Token for window that is currently * controlling gridding. */{ TkWindow *winPtr = (TkWindow *) tkwin; register WmInfo *wmPtr; /* * Find the top-level window for tkwin, plus the window manager * information. */ while (!(winPtr->flags & TK_TOP_LEVEL)) { winPtr = winPtr->parentPtr; } wmPtr = winPtr->wmInfoPtr; if (tkwin != wmPtr->gridWin) { return; } wmPtr->gridWin = NULL; wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); if (wmPtr->width != -1) { wmPtr->width = winPtr->reqWidth + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc; wmPtr->height = winPtr->reqHeight + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc; } wmPtr->widthInc = 1; wmPtr->heightInc = 1; wmPtr->flags |= WM_UPDATE_SIZE_HINTS; if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); wmPtr->flags |= WM_UPDATE_PENDING; }}/* *---------------------------------------------------------------------- * * TopLevelEventProc -- * * This procedure is invoked when a top-level (or other externally- * managed window) is restructured in any way. * * Results: * None. * * Side effects: * Tk's internal data structures for the window get modified to * reflect the structural change. * *---------------------------------------------------------------------- */static voidTopLevelEventProc( ClientData clientData, /* Window for which event occurred. */ XEvent *eventPtr) /* Event that just happened. */{ register TkWindow *winPtr = (TkWindow *) clientData; winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE; if (eventPtr->type == DestroyNotify) { Tk_ErrorHandler handler; if (!(winPtr->flags & TK_ALREADY_DEAD)) { /* * A top-level window was deleted externally (e.g., by the window * manager). This is probably not a good thing, but cleanup as * best we can. The error handler is needed because * Tk_DestroyWindow will try to destroy the window, but of course * it's already gone. */ handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); Tk_DestroyWindow((Tk_Window) winPtr); Tk_DeleteErrorHandler(handler); } if (wmTracing) { printf("TopLevelEventProc: %s deleted\n", winPtr->pathName); } } else if (eventPtr->type == ReparentNotify) { panic("recieved unwanted reparent event"); }}/* *---------------------------------------------------------------------- * * TopLevelReqProc -- * * This procedure is invoked by the geometry manager whenever * the requested size for a top-level window is changed. * * Results: * None. * * Side effects: * Arrange for the window to be resized to satisfy the request * (this happens as a when-idle action). * *---------------------------------------------------------------------- */ /* ARGSUSED */static voidTopLevelReqProc( ClientData dummy, /* Not used. */ Tk_Window tkwin) /* Information about window. */{ TkWindow *winPtr = (TkWindow *) tkwin; WmInfo *wmPtr; wmPtr = winPtr->wmInfoPtr; wmPtr->flags |= WM_UPDATE_SIZE_HINTS; if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); wmPtr->flags |= WM_UPDATE_PENDING; }}/* *---------------------------------------------------------------------- * * UpdateGeometryInfo -- * * This procedure is invoked when a top-level window is first * mapped, and also as a when-idle procedure, to bring the * geometry and/or position of a top-level window back into * line with what has been requested by the user and/or widgets. * This procedure doesn't return until the window manager has * responded to the geometry change. * * Results: * None. * * Side effects: * The window's size and location may change, unless the WM prevents * that from happening. * *---------------------------------------------------------------------- */static voidUpdateGeometryInfo( ClientData clientData) /* Pointer to the window's record. */{ register TkWindow *winPtr = (TkWindow *) clientData; register WmInfo *wmPtr = winPtr->wmInfoPtr; int x, y, width, height; unsigned long serial; wmPtr->flags &= ~WM_UPDATE_PENDING; /* * Compute the new size for the top-level window. See the * user documentation for details on this, but the size * 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. */ if (wmPtr->width == -1) { width = winPtr->reqWidth; } else if (wmPtr->gridWin != NULL) { width = winPtr->reqWidth + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc; } else { width = wmPtr->width; } if (width <= 0) { width = 1; } if (wmPtr->height == -1) { height = winPtr->reqHeight; } else if (wmPtr->gridWin != NULL) { height = winPtr->reqHeight + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc; } else { height = wmPtr->height; } if (height <= 0) { height = 1; } /* * Compute the new position for the upper-left pixel of the window's * decorative frame. This is tricky, because we need to include the * border widths supplied by a reparented parent in this calculation, * but can't use the parent's current overall size since that may * change as a result of this code. */ if (wmPtr->flags & WM_NEGATIVE_X) { x = wmPtr->vRootWidth - wmPtr->x - (width + (wmPtr->parentWidth - winPtr->changes.width)); } else { x = wmPtr->x; } if (wmPtr->flags & WM_NEGATIVE_Y) { y = wmPtr->vRootHeight - wmPtr->y - (height + (wmPtr->parentHeight - winPtr->changes.height)); } else { y = wmPtr->y; } /* * If the window's size is going to change and the window is * supposed to not be resizable by the user, then we have to * update the size hints. There may also be a size-hint-update * request pending from somewhere else, too. */ if (((width != winPtr->changes.width) || (height != winPtr->changes.height)) && (wmPtr->gridWin == NULL) && ((wmPtr->sizeHintsFlags & (PMinSize|PMaxSize)) == 0)) { wmPtr->flags |= WM_UPDATE_SIZE_HINTS; } if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) { UpdateSizeHints(winPtr); } /* * Reconfigure the window if it isn't already configured correctly. * A few tricky points: * * 1. If the window is embedded and the container is also in this * process, don't actually reconfigure the window; just pass the * desired size on to the container. Also, zero out any position * information, since embedded windows are not allowed to move. * 2. Sometimes the window manager will give us a different size * than we asked for (e.g. mwm has a minimum size for windows), so * base the size check on what we *asked for* last time, not what we * got. * 3. Don't move window unless a new position has been requested for * it. This is because of "features" in some window managers (e.g. * twm, as of 4/24/91) where they don't interpret coordinates * according to ICCCM. Moving a window to its current location may * cause it to shift position on the screen. */ if (Tk_IsEmbedded(winPtr)) { TkWindow *contWinPtr; contWinPtr = TkpGetOtherWindow(winPtr); /* * NOTE: Here we should handle out of process embedding. */ if (contWinPtr != NULL) { /* * This window is embedded and the container is also in this * process, so we don't need to do anything special about the * geometry, except to make sure that the desired size is known * by the container. Also, zero out any position information, * since embedded windows are not allowed to move. */ wmPtr->x = wmPtr->y = 0; wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); Tk_GeometryRequest((Tk_Window) contWinPtr, width, height); } return; } serial = NextRequest(winPtr->display); if (wmPtr->flags & WM_MOVE_PENDING) { wmPtr->configWidth = width; wmPtr->configHeight = height; if (wmTracing) { printf( "UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n", x, y, width, height); } Tk_MoveResizeWindow((Tk_Window) winPtr, x, y, (unsigned) width, (unsigned) height); } else if ((width != wmPtr->configWidth) || (height != wmPtr->configHeight)) { wmPtr->configWidth = width; wmPtr->configHeight = height; if (wmTracing) { printf("UpdateGeometryInfo resizing to %d x %d\n", width, height); } Tk_ResizeWindow((Tk_Window) winPtr, (unsigned) width, (unsigned) height); } else { return; }}/* *-------------------------------------------------------------- * * UpdateSizeHints -- * * This procedure is called to update the window manager's * size hints information from the information in a WmInfo * structure. * * Results: * None. * * Side effects: * Properties get changed for winPtr. * *-------------------------------------------------------------- */static voidUpdateSizeHints( TkWindow *winPtr){ register WmInfo *wmPtr = winPtr->wmInfoPtr; XSizeHints *hintsPtr; wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS; hintsPtr = XAllocSizeHints(); if (hintsPtr == NULL) { return; } /* * Compute the pixel-based sizes for the various fields in the * size hints structure, based on the grid-based sizes in * our structure. */ if (wmPtr->gridWin != NULL) { hintsPtr->base_width = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); if (hintsPtr->base_width < 0) { hintsPtr->base_width = 0; } hintsPtr->base_height = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); if (hintsPtr->base_height < 0) { hintsPtr->base_height = 0; } hintsPtr->min_width = hintsPtr->base_width + (wmPtr->minWidth * wmPtr->widthInc); hintsPtr->min_height = hintsPtr->base_height + (wmPtr->minHeight * wmPtr->heightInc); hintsPtr->max_width = hintsPtr->base_width + (wmPtr->maxWidth * wmPtr->widthInc); hintsPtr->max_height = hintsPtr->base_height + (wmPtr->maxHeight * wmPtr->heightInc); } else { hintsPtr->min_width = wmPtr->minWidth; hintsPtr->min_height = wmPtr->minHeight; hintsPtr->max_width = wmPtr->maxWidth; hintsPtr->max_height = wmPtr->maxHeight; hintsPtr->base_width = 0; hintsPtr->base_height = 0; } hintsPtr->width_inc = wmPtr->widthInc; hintsPtr->height_inc = wmPtr->heightInc; hintsPtr->min_aspect.x = wmPtr->minAspect.x; hintsPtr->min_aspect.y = wmPtr->minAspect.y; hintsPtr->max_aspect.x = wmPtr->maxAspect.x; hintsPtr->max_aspect.y = wmPtr->maxAspect.y; hintsPtr->win_gravity = wmPtr->gravity; hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize | PMaxSize; /* * If the window isn't supposed to be resizable, then set the * minimum and maximum dimensions to be the same. */ 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; } if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { if (wmPtr->height >= 0) { hintsPtr->min_height = wmPtr->height; } else { hintsPtr->min_height = winPtr->reqHeight; } hintsPtr->max_height = hintsPtr->min_height; } XSetWMNormalHints(winPtr->display, winPtr->window, hintsPtr); XFree((char *) hintsPtr);}/* *-------------------------------------------------------------- * * ParseGeometry -- * * This procedure parses a geometry string and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -