📄 tkunixwm.c
字号:
/* * tkUnixWm.c -- * * This module takes care of the interactions between a Tk-based * application and the window manager. Among other things, it * implements the "wm" command and passes geometry information * to the window manager. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkUnixWm.c 1.155 97/10/28 08:35:19 */#include "tkPort.h"#include "tkInt.h"#include "tkUnixInt.h"#include <errno.h>/* * A data structure of the following type holds information for * each window manager protocol (such as WM_DELETE_WINDOW) for * which a handler (i.e. a Tcl command) has been defined for a * particular top-level window. */typedef struct ProtocolHandler { Atom protocol; /* Identifies the protocol. */ struct ProtocolHandler *nextPtr; /* Next in list of protocol handlers for * the same top-level window, or NULL for * end of list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ char command[4]; /* Tcl command to invoke when a client * message for this protocol arrives. * The actual size of the structure varies * to accommodate the needs of the actual * command. THIS MUST BE THE LAST FIELD OF * THE STRUCTURE. */} ProtocolHandler;#define HANDLER_SIZE(cmdLength) \ ((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))/* * A data structure of the following type holds window-manager-related * information for each top-level window in an application. */typedef struct TkWmInfo { TkWindow *winPtr; /* Pointer to main Tk information for * this window. */ Window reparent; /* If the window has been reparented, this * gives the ID of the ancestor of the window * that is a child of the root window (may * not be window's immediate parent). If * the window isn't reparented, this has the * value None. */ char *title; /* Title to display in window caption. If * NULL, use name of widget. Malloced. */ char *iconName; /* Name to display in icon. Malloced. */ Window master; /* Master window for TRANSIENT_FOR property, * or None. */ XWMHints hints; /* Various pieces of information for * window manager. */ char *leaderName; /* Path name of leader of window group * (corresponds to hints.window_group). * Malloc-ed. Note: this field doesn't * get updated if leader is destroyed. */ char *masterWindowName; /* Path name of window specified as master * in "wm transient" command, or NULL. * Malloc-ed. Note: this field doesn't * get updated if masterWindowName is * destroyed. */ Tk_Window icon; /* Window to use as icon for this window, * or NULL. */ Tk_Window iconFor; /* Window for which this window is icon, or * NULL if this isn't an icon for anyone. */ int withdrawn; /* Non-zero means window has been withdrawn. */ /* * In order to support menubars transparently under X, each toplevel * window is encased in an additional window, called the wrapper, * that holds the toplevel and the menubar, if any. The information * below is used to keep track of the wrapper and the menubar. */ TkWindow *wrapperPtr; /* Pointer to information about the wrapper. * This is the "real" toplevel window as * seen by the window manager. Although * this is an official Tk window, it * doesn't appear in the application's * window hierarchy. NULL means that * the wrapper hasn't been created yet. */ Tk_Window menubar; /* Pointer to information about the * menubar, or NULL if there is no * menubar for this toplevel. */ int menuHeight; /* Amount of vertical space needed for * menubar, measured in pixels. If * menubar is non-NULL, this is >= 1 (X * servers don't like dimensions of 0). */ /* * Information used to construct an XSizeHints structure for * the window manager: */ int sizeHintsFlags; /* Flags word for XSizeHints structure. * If the PBaseSize flag is set then the * window is gridded; otherwise it isn't * gridded. */ int minWidth, minHeight; /* Minimum dimensions of window, in * grid units, not pixels. */ int maxWidth, maxHeight; /* Maximum dimensions of window, in * grid units, not pixels. */ Tk_Window gridWin; /* Identifies the window that controls * gridding for this top-level, or NULL if * the top-level isn't currently gridded. */ int widthInc, heightInc; /* Increments for size changes (# pixels * per step). */ struct { int x; /* numerator */ int y; /* denominator */ } minAspect, maxAspect; /* Min/max aspect ratios for window. */ int reqGridWidth, reqGridHeight; /* The dimensions of the window (in * grid units) requested through * the geometry manager. */ int gravity; /* Desired window gravity. */ /* * Information used to manage the size and location of a window. */ int width, height; /* Desired dimensions of window, specified * in grid units. These values are * set by the "wm geometry" command and by * ConfigureNotify events (for when wm * resizes window). -1 means user hasn't * requested dimensions. */ int x, y; /* Desired X and Y coordinates for window. * These values are set by "wm geometry", * plus by ConfigureNotify events (when wm * moves window). These numbers are * different than the numbers stored in * winPtr->changes because (a) they could be * measured from the right or bottom edge * of the screen (see WM_NEGATIVE_X and * WM_NEGATIVE_Y flags) and (b) if the window * has been reparented then they refer to the * parent rather than the window itself. */ int parentWidth, parentHeight; /* Width and height of reparent, in pixels * *including border*. If window hasn't been * reparented then these will be the outer * dimensions of the window, including * border. */ int xInParent, yInParent; /* Offset of wrapperPtr within reparent, * measured in pixels from upper-left outer * corner of reparent's border to upper-left * outer corner of wrapperPtr's border. If * not reparented then these are zero. */ int configWidth, configHeight; /* Dimensions passed to last request that we * issued to change geometry of the wrapper. * Used to eliminate redundant resize * operations. */ /* * Information about the virtual root window for this top-level, * if there is one. */ Window vRoot; /* Virtual root window for this top-level, * or None if there is no virtual root * window (i.e. just use the screen's root). */ int vRootX, vRootY; /* Position of the virtual root inside the * root window. If the WM_VROOT_OFFSET_STALE * flag is set then this information may be * incorrect and needs to be refreshed from * the X server. If vRoot is None then these * values are both 0. */ int vRootWidth, vRootHeight;/* Dimensions of the virtual root window. * If vRoot is None, gives the dimensions * of the containing screen. This information * is never stale, even though vRootX and * vRootY can be. */ /* * Miscellaneous information. */ ProtocolHandler *protPtr; /* First in list of protocol handlers for * this window (NULL means none). */ int cmdArgc; /* Number of elements in cmdArgv below. */ char **cmdArgv; /* Array of strings to store in the * WM_COMMAND property. NULL means nothing * available. */ char *clientMachine; /* String to store in WM_CLIENT_MACHINE * property, or NULL. */ int flags; /* Miscellaneous flags, defined below. */ struct TkWmInfo *nextPtr; /* Next in list of all top-level windows. */} WmInfo;/* * Flag values for WmInfo structures: * * WM_NEVER_MAPPED - non-zero means window has never been * mapped; need to update all info when * window is first mapped. * WM_UPDATE_PENDING - non-zero means a call to UpdateGeometryInfo * has already been scheduled for this * window; no need to schedule another one. * WM_NEGATIVE_X - non-zero means x-coordinate is measured in * pixels from right edge of screen, rather * than from left edge. * WM_NEGATIVE_Y - non-zero means y-coordinate is measured in * pixels up from bottom of screen, rather than * down from top. * WM_UPDATE_SIZE_HINTS - non-zero means that new size hints need to be * propagated to window manager. * WM_SYNC_PENDING - set to non-zero while waiting for the window * manager to respond to some state change. * WM_VROOT_OFFSET_STALE - non-zero means that (x,y) offset information * about the virtual root window is stale and * needs to be fetched fresh from the X server. * WM_ABOUT_TO_MAP - non-zero means that the window is about to * be mapped by TkWmMapWindow. This is used * by UpdateGeometryInfo to modify its behavior. * WM_MOVE_PENDING - non-zero means the application has requested * a new position for the window, but it hasn't * been reflected through the window manager * yet. * WM_COLORMAPS_EXPLICIT - non-zero means the colormap windows were * set explicitly via "wm colormapwindows". * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows" * was called the top-level itself wasn't * specified, so we added it implicitly at * the end of the list. * WM_WIDTH_NOT_RESIZABLE - non-zero means that we're not supposed to * allow the user to change the width of the * window (controlled by "wm resizable" * command). * WM_HEIGHT_NOT_RESIZABLE - non-zero means that we're not supposed to * allow the user to change the height of the * window (controlled by "wm resizable" * command). */#define WM_NEVER_MAPPED 1#define WM_UPDATE_PENDING 2#define WM_NEGATIVE_X 4#define WM_NEGATIVE_Y 8#define WM_UPDATE_SIZE_HINTS 0x10#define WM_SYNC_PENDING 0x20#define WM_VROOT_OFFSET_STALE 0x40#define WM_ABOUT_TO_MAP 0x100#define WM_MOVE_PENDING 0x200#define WM_COLORMAPS_EXPLICIT 0x400#define WM_ADDED_TOPLEVEL_COLORMAP 0x800#define WM_WIDTH_NOT_RESIZABLE 0x1000#define WM_HEIGHT_NOT_RESIZABLE 0x2000/* * This module keeps a list of all top-level windows, primarily to * simplify the job of Tk_CoordsToWindow. */static WmInfo *firstWmPtr = NULL; /* Points to first top-level window. *//* * The variable below is used to enable or disable tracing in this * module. If tracing is enabled, then information is printed on * standard output about interesting interactions with the window * manager. */static int wmTracing = 0;/* * The following structures are the official type records for geometry * management of top-level and menubar windows. */static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy, Tk_Window tkwin));static Tk_GeomMgr wmMgrType = { "wm", /* name */ TopLevelReqProc, /* requestProc */ (Tk_GeomLostSlaveProc *) NULL, /* lostSlaveProc */};static void MenubarReqProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin));static Tk_GeomMgr menubarMgrType = { "menubar", /* name */ MenubarReqProc, /* requestProc */ (Tk_GeomLostSlaveProc *) NULL, /* lostSlaveProc */};/* * Structures of the following type are used for communication between * WaitForEvent, WaitRestrictProc, and WaitTimeoutProc. */typedef struct WaitRestrictInfo { Display *display; /* Window belongs to this display. */ Window window; /* We're waiting for events on this window. */ int type; /* We only care about this type of event. */ XEvent *eventPtr; /* Where to store the event when it's found. */ int foundEvent; /* Non-zero means that an event of the * desired type has been found. */} WaitRestrictInfo;/* * Forward declarations for procedures defined in this file: */static int ComputeReparentGeometry _ANSI_ARGS_((WmInfo *wmPtr));static void ConfigureEvent _ANSI_ARGS_((WmInfo *wmPtr, XConfigureEvent *eventPtr));static void CreateWrapper _ANSI_ARGS_((WmInfo *wmPtr));static void GetMaxSize _ANSI_ARGS_((WmInfo *wmPtr, int *maxWidthPtr, int *maxHeightPtr));static void MenubarDestroyProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static int ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp, char *string, TkWindow *winPtr));static void ReparentEvent _ANSI_ARGS_((WmInfo *wmPtr, XReparentEvent *eventPtr));static void TopLevelReqProc _ANSI_ARGS_((ClientData dummy, Tk_Window tkwin));static void UpdateGeometryInfo _ANSI_ARGS_(( ClientData clientData));static void UpdateHints _ANSI_ARGS_((TkWindow *winPtr));static void UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr));static void UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr));static void UpdateWmProtocols _ANSI_ARGS_((WmInfo *wmPtr));static void WaitForConfigureNotify _ANSI_ARGS_((TkWindow *winPtr, unsigned long serial));static int WaitForEvent _ANSI_ARGS_((Display *display, Window window, int type, XEvent *eventPtr));static void WaitForMapNotify _ANSI_ARGS_((TkWindow *winPtr, int mapped));static Tk_RestrictAction WaitRestrictProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static void WrapperEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));/* *-------------------------------------------------------------- * * TkWmNewWindow -- * * This procedure is invoked whenever a new top-level * window is created. Its job is to initialize the WmInfo * structure for the window. * * Results: * None. * * Side effects: * A WmInfo structure gets allocated and initialized. * *-------------------------------------------------------------- */voidTkWmNewWindow(winPtr) TkWindow *winPtr; /* Newly-created top-level window. */{ register WmInfo *wmPtr; wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo)); wmPtr->winPtr = winPtr; wmPtr->reparent = None; wmPtr->title = NULL; wmPtr->iconName = NULL; wmPtr->master = None; wmPtr->hints.flags = InputHint | StateHint; wmPtr->hints.input = True; wmPtr->hints.initial_state = NormalState; wmPtr->hints.icon_pixmap = None; wmPtr->hints.icon_window = None; wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0; wmPtr->hints.icon_mask = None; wmPtr->hints.window_group = None; wmPtr->leaderName = NULL; wmPtr->masterWindowName = NULL; wmPtr->icon = NULL; wmPtr->iconFor = NULL; wmPtr->withdrawn = 0; wmPtr->wrapperPtr = NULL; wmPtr->menubar = NULL; wmPtr->menuHeight = 0; wmPtr->sizeHintsFlags = 0; wmPtr->minWidth = wmPtr->minHeight = 1; /* * Default the maximum dimensions to the size of the display, minus * a guess about how space is needed for window manager decorations. */ wmPtr->maxWidth = 0; wmPtr->maxHeight = 0; wmPtr->gridWin = NULL; wmPtr->widthInc = wmPtr->heightInc = 1; wmPtr->minAspect.x = wmPtr->minAspect.y = 1; wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1; wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -