tkUnixWm.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/*
* 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-1996 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.124 96/03/29 14:05:44
*/
#include "tkInt.h"
#include <errno.h>
#ifndef WithdrawnState
#define WithdrawnState 0
#define Ancient 1
#endif
#ifndef PBaseSize
#define PBaseSize 0
#endif
/*
* 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 {
struct ProtocolHandler *nextPtr;
/* Next in list of protocol handlers for
* the same top-level window, or NULL for
* end of list. */
* 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. */
#define HANDLER_SIZE(cmdLength) \
/*
* A data structure of the following type holds window-manager-related
* information for each top-level window in an application.
*/
typedef struct TkWmInfo {
* this window. */
* 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. */
* NULL, use name of widget. */
* or None. */
* window manager. */
* (corresponds to hints.window_group).
* Note: this field doesn't get updated
* if leader is destroyed. */
* in "wm transient" command, or NULL.
* Note: this field doesn't get updated if
* masterWindowName is destroyed. */
* or NULL. */
* NULL if this isn't an icon for anyone. */
int withdrawn; /* Non-zero means window has been withdrawn. */
/*
* 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. */
* grid units, not pixels. */
* grid units, not pixels. */
* gridding for this top-level, or NULL if
* the top-level isn't currently gridded. */
* per step). */
struct {
int x; /* numerator */
int y; /* denominator */
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.
*/
* 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. */
* from upper-left outer corner of parent's
* border to upper-left outer corner of child's
* border. If not reparented then these are
* zero. */
int configWidth, configHeight;
/* Dimensions passed to last request that we
* issued to change geometry of window. Used
* to eliminate redundant resize operations. */
/*
* Information about the virtual root window for this top-level,
* if there is one.
*/
* or None if there is no virtual root
* window (i.e. just use the screen's root). */
* 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. */
* 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.
*/
* 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. */
} 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.
*/
/*
* 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 structure is the official type record for geometry
* management of top-level windows.
*/
static Tk_GeomMgr wmMgrType = {
"wm", /* name */
TopLevelReqProc, /* requestProc */
};
/*
* Structures of the following type are used for communication between
* WaitForEvent, WaitRestrictProc, and WaitTimeoutProc.
*/
typedef struct WaitRestrictInfo {
int type; /* We only care about this type of event. */
int foundEvent; /* Non-zero means that an event of the
* desired type has been found. */
int timeout; /* Non-zero means that too much time elapsed
* while waiting, and we should just give
* up. */
/*
* Forward declarations for procedures defined in this file:
*/
int *maxWidthPtr, int *maxHeightPtr));
static void UpdateGeometryInfo _ANSI_ARGS_((
unsigned long serial));
int mapped));
static Tk_RestrictAction
/*
*--------------------------------------------------------------
*
* 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.
*
*--------------------------------------------------------------
*/
void
{
wmPtr->sizeHintsFlags = 0;
/*
* Default the maximum dimensions to the size of the display, minus
* a guess about how space is needed for window manager decorations.
*/
firstWmPtr = wmPtr;
/*
* Tk must monitor structure events for top-level windows, in order
* to detect size and position changes caused by window managers.
*/
/*
* Arrange for geometry requests to be reflected from the window
* to the window manager.
*/
}
/*
*--------------------------------------------------------------
*
* TkWmMapWindow --
*
* This procedure is invoked to map a top-level window. This
* module gets a chance to update all window-manager-related
* information in properties before the window manager sees
* the map event and checks the properties. It also gets to
* decide whether or not to even map the window after all.
*
* Results:
* None.
*
* Side effects:
* Properties of winPtr may get updated to provide up-to-date
* information to the window manager. The window may also get
* mapped, but it may not be if this procedure decides that
* isn't appropriate (e.g. because the window is withdrawn).
*
*--------------------------------------------------------------
*/
void
* be mapped. */
{
#if !Ancient
/*
* This is the first time this window has ever been mapped.
* Store all the window-manager-related information for the
* window.
*/
}
}
}
}
}
!= 0) {
&textProp);
}
}
}
#endif
return;
}
/*
* This window is an icon for somebody else. Make sure that
* the geometry is up-to-date, then return without mapping
* the window.
*/
}
return;
}
}
/*
* Map the window, then wait to be sure that the window manager has
* processed the map operation.
*/
}
}
/*
*--------------------------------------------------------------
*
* TkWmUnmapWindow --
*
* This procedure is invoked to unmap a top-level window. The
* only thing it does special is to wait for the window actually
* to be unmapped.
*
* Results:
* None.
*
* Side effects:
* Unmaps the window.
*
*--------------------------------------------------------------
*/
void
* be mapped. */
{
/*
* It seems to be important to wait after unmapping a top-level
* window until the window really gets unmapped. I don't completely
* understand all the interactions with the window manager, but if
* we go on without waiting, and if the window is then mapped again
* quickly, events seem to get lost so that we think the window isn't
* mapped when in fact it is mapped. I suspect that this has something
* to do with the window manager filtering Map events (and possily not
* filtering Unmap events?).
*/
WaitForMapNotify(winPtr, 0);
}
/*
*--------------------------------------------------------------
*
* TkWmDeadWindow --
*
* This procedure is invoked when a top-level window is
* about to be deleted. It cleans up the wm-related data
* structures for the window.
*
* Results:
* None.
*
* Side effects:
* The WmInfo structure for winPtr gets freed up.
*
*--------------------------------------------------------------
*/
void
{
return;
}
if (firstWmPtr == wmPtr) {
} else {
panic("couldn't unlink window in TkWmDeadWindow");
}
break;
}
}
}
}
}
}
}
}
}
}
}
}
/*
*--------------------------------------------------------------
*
* TkWmSetClass --
*
* This procedure is invoked whenever a top-level window's
* class is changed. If the window has been mapped then this
* procedure updates the window manager property for the
* class. If the window hasn't been mapped, the update is
* deferred until just before the first mapping.
*
* Results:
* None.
*
* Side effects:
* A window property may get updated.
*
*--------------------------------------------------------------
*/
void
{
return;
}
classPtr = XAllocClassHint();
}
}
/*
*----------------------------------------------------------------------
*
* Tk_WmCmd --
*
* This procedure is invoked to process the "wm" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
int
* interpreter. */
int argc; /* Number of arguments. */
char **argv; /* Argument strings. */
{
int c;
if (argc < 2) {
return TCL_ERROR;
}
c = argv[1][0];
&& (length >= 3)) {
return TCL_ERROR;
}
if (argc == 2) {
return TCL_OK;
}
}
if (argc < 3) {
goto wrongNumArgs;
}
return TCL_ERROR;
}
"\" isn't a top-level window", (char *) NULL);
return TCL_ERROR;
}
argv[0], " aspect window ?minNumer minDenom ",
"maxNumer maxDenom?\"", (char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
return TCL_ERROR;
}
(denom2 <= 0)) {
return TCL_ERROR;
}
}
goto updateGeom;
&& (length >= 2)) {
argv[0], " client window ?name?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
if (argv[3][0] == 0) {
"WM_CLIENT_MACHINE"));
}
}
return TCL_OK;
}
}
wmPtr->clientMachine = (char *)
#if !Ancient
!= 0) {
&textProp);
}
}
#endif
&& (length >= 3)) {
argv[0], " colormapwindows window ?windowList?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
}
for (i = 0; i < count; i++) {
if ((i == (count-1))
break;
}
cmapList[i]);
} else {
}
}
return TCL_OK;
}
!= TCL_OK) {
return TCL_ERROR;
}
gotToplevel = 0;
for (i = 0; i < windowArgc; i++) {
tkwin);
ckfree((char *) windowArgv);
return TCL_ERROR;
}
gotToplevel = 1;
}
}
}
if (!gotToplevel) {
windowArgc++;
} else {
}
ckfree((char *) windowArgv);
return TCL_OK;
&& (length >= 3)) {
int cmdArgc;
char **cmdArgv;
argv[0], " command window ?value?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
if (argv[3][0] == 0) {
}
}
return TCL_OK;
}
return TCL_ERROR;
}
}
}
if (argc != 3) {
return TCL_ERROR;
}
return TCL_ERROR;
}
return TCL_OK;
}
&& (length >= 2)) {
argv[0], " focusmodel window ?active|passive?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
}
c = argv[3][0];
} else {
"\": must be active or passive", (char *) NULL);
return TCL_ERROR;
}
&& (length >= 2)) {
if (argc != 3) {
return TCL_ERROR;
}
}
&& (length >= 2)) {
argv[0], " geometry window ?newGeometry?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
} else {
}
return TCL_OK;
}
goto updateGeom;
}
&& (length >= 3)) {
argv[0], " grid window ?baseWidth baseHeight ",
"widthInc heightInc?\"", (char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
/*
* Turn off gridding and reset the width and height
* to make sense as ungridded numbers.
*/
}
} else {
return TCL_ERROR;
}
if (reqWidth < 0) {
return TCL_ERROR;
}
if (reqHeight < 0) {
return TCL_ERROR;
}
if (widthInc < 0) {
return TCL_ERROR;
}
if (heightInc < 0) {
return TCL_ERROR;
}
}
goto updateGeom;
&& (length >= 3)) {
argv[0], " group window ?pathName?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
return TCL_ERROR;
}
}
&& (length >= 5)) {
argv[0], " iconbitmap window ?bitmap?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
}
} else {
return TCL_ERROR;
}
}
&& (length >= 5)) {
if (argc != 3) {
return TCL_ERROR;
}
"\": override-redirect flag is set", (char *) NULL);
return TCL_ERROR;
}
"\": it is a transient", (char *) NULL);
return TCL_ERROR;
}
return TCL_ERROR;
}
return TCL_OK;
}
} else {
"couldn't send iconify message to window manager";
return TCL_ERROR;
}
WaitForMapNotify(winPtr, 0);
}
&& (length >= 5)) {
argv[0], " iconmask window ?bitmap?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
}
} else {
return TCL_ERROR;
}
}
&& (length >= 5)) {
if (argc > 4) {
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
} else {
}
}
&& (length >= 5)) {
int x, y;
argv[0], " iconposition window ?x y?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
return TCL_ERROR;
}
}
&& (length >= 5)) {
argv[0], " iconwindow window ?pathName?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
/*
* Remove the icon window relationship. In principle we
* should also re-enable button events for the window, but
* this doesn't work in general because the window manager
* is probably selecting on them (we'll get an error if
* we try to re-enable the events). So, just leave the
* icon window event-challenged; the user will have to
* recreate it if they want button events.
*/
}
} else {
return TCL_ERROR;
}
if (!Tk_IsTopLevel(tkwin2)) {
" as icon window: not at top level", (char *) NULL);
return TCL_ERROR;
}
return TCL_ERROR;
}
/*
* Let the window use button events again.
*/
}
/*
* Disable button events in the icon window: some window
* managers (like olvwm) want to get the events themselves,
* but X only allows one application at a time to receive
* button events for a window.
*/
& ~ButtonPressMask;
Tk_ScreenNumber(tkwin2)) == 0) {
"couldn't send withdraw message to window manager";
return TCL_ERROR;
}
}
}
&& (length >= 2)) {
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
}
return TCL_ERROR;
}
goto updateGeom;
&& (length >= 2)) {
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
}
return TCL_ERROR;
}
goto updateGeom;
} else if ((c == 'o')
int boolean;
argv[0], " overrideredirect window ?boolean?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
} else {
}
return TCL_OK;
}
return TCL_ERROR;
}
&atts);
&& (length >= 2)) {
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
c = argv[3][0];
} else {
"\": must be program or user", (char *) NULL);
return TCL_ERROR;
}
}
goto updateGeom;
&& (length >= 2)) {
int cmdLength;
argv[0], " protocol window ?name? ?command?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
/*
* Return a list of all defined protocols for the window.
*/
}
return TCL_OK;
}
if (argc == 4) {
/*
* Return the command to handle a given protocol.
*/
return TCL_OK;
}
}
return TCL_OK;
}
/*
* Delete any current protocol handler, then create a new
* one with the specified command, unless the command is
* empty.
*/
} else {
}
break;
}
}
if (cmdLength > 0) {
}
}
argv[0], " resizable window ?width height?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
}
return TCL_ERROR;
}
if (width) {
} else {
}
if (height) {
} else {
}
goto updateGeom;
&& (length >= 2)) {
argv[0], " sizefrom window ?user|program?\"",
(char *) NULL);
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
c = argv[3][0];
} else if ((c == 'p')
} else {
"\": must be program or user", (char *) NULL);
return TCL_ERROR;
}
}
goto updateGeom;
&& (length >= 2)) {
if (argc != 3) {
return TCL_ERROR;
}
} else {
}
&& (length >= 2)) {
if (argc > 4) {
return TCL_ERROR;
}
if (argc == 3) {
return TCL_OK;
} else {
#if !Ancient
&textProp) != 0) {
}
}
#endif
}
&& (length >= 3)) {
return TCL_ERROR;
}
if (argc == 3) {
}
return TCL_OK;
}
} else {
return TCL_ERROR;
}
}
}
if (argc != 3) {
return TCL_ERROR;
}
(char *) NULL);
return TCL_ERROR;
}
return TCL_OK;
}
"couldn't send withdraw message to window manager";
return TCL_ERROR;
}
WaitForMapNotify(winPtr, 0);
} else {
"\": must be aspect, client, command, deiconify, ",
"focusmodel, frame, geometry, grid, group, iconbitmap, ",
"iconify, iconmask, iconname, iconposition, ",
"iconwindow, maxsize, minsize, overrideredirect, ",
"positionfrom, protocol, resizable, sizefrom, state, title, ",
"transient, or withdraw",
(char *) NULL);
return TCL_ERROR;
}
return TCL_OK;
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tk_SetGrid --
*
* This procedure is invoked by a widget when it wishes to set a grid
* coordinate system that controls the size of a top-level window.
* It provides a C interface equivalent to the "wm grid" command and
* is usually asscoiated with the -setgrid option.
*
* Results:
* None.
*
* Side effects:
* Grid-related information will be passed to the window manager, so
* that the top-level window associated with tkwin will resize on
* even grid units. If some other window already controls gridding
* for the top-level window then this procedure call has no effect.
*
*----------------------------------------------------------------------
*/
void
* will be posted for the top-level window
* associated with this window. */
int reqWidth; /* Width (in grid units) corresponding to
* the requested geometry for tkwin. */
int reqHeight; /* Height (in grid units) corresponding to
* the requested geometry for tkwin. */
* change of one grid unit. */
{
/*
* Find the top-level window for tkwin, plus the window manager
* information.
*/
/*
* The window is being deleted... just skip this operation.
*/
return;
}
}
return;
}
== PBaseSize|PResizeInc)) {
return;
}
/*
* If gridding was previously off, then forget about any window
* size requests made by the user or via "wm geometry": these are
* in pixel units and there's no easy way to translate them to
* grid units since the new requested size of the top-level window in
* pixels may not yet have been registered yet (it may filter up
* the hierarchy in DoWhenIdle handlers). However, if the window
* has never been mapped yet then just leave the window size alone:
* assume that it is intended to be in grid units but just happened
* to have been specified before this procedure was called.
*/
}
/*
* Set the new gridding information, and start the process of passing
* all of this information to the window manager.
*/
}
}
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
void
* controlling gridding. */
{
/*
* Find the top-level window for tkwin, plus the window manager
* information.
*/
/*
* The window is being deleted... just skip this operation.
*/
return;
}
}
return;
}
}
}
}
/*
*----------------------------------------------------------------------
*
* ConfigureEvent --
*
* This procedure is called to handle ConfigureNotify events on
* top-level windows.
*
* Results:
* None.
*
* Side effects:
* Information gets updated in the WmInfo structure for the window.
*
*----------------------------------------------------------------------
*/
static void
* winPtr. */
{
/*
* Update size information from the event. There are a couple of
* tricky points here:
*
* 1. If the user changed the size externally then set wmPtr->width
* and wmPtr->height just as if a "wm geometry" command had been
* invoked with the same information.
* 2. However, if the size is changing in response to a request
* coming from us (WM_SYNC_PENDING is set), then don't set wmPtr->width
* or wmPtr->height if they were previously -1 (otherwise the
* window will stop tracking geometry manager requests).
*/
if (wmTracing) {
printf("TopLevelEventProc: user changed %s size to %dx%d\n",
}
/*
* Don't set external width, since the user didn't change it
* from what the widgets asked for.
*/
} else {
+ (configEventPtr->width
}
} else {
}
}
/*
* Don't set external height, since the user didn't change it
* from what the widgets asked for.
*/
} else {
+ (configEventPtr->height
}
} else {
}
}
}
if (wmTracing) {
printf("ConfigureEvent: %s x = %d y = %d, width = %d, height = %d",
}
/*
* Reparenting window managers make life difficult. If the
* window manager reparents a top-level window then the x and y
* information that comes in events for the window is wrong:
* it gives the location of the window inside its decorative
* parent, rather than the location of the window in root
* coordinates, which is what we want. Window managers
* are supposed to send synthetic events with the correct
* information, but ICCCM doesn't require them to do this
* under all conditions, and the information provided doesn't
* include everything we need here. So, the code below
* maintains a bunch of information about the parent window.
* If the window hasn't been reparented, we pretend that
* there is a parent shrink-wrapped around the window.
*/
}
}
}
}
/*
*----------------------------------------------------------------------
*
* ReparentEvent --
*
* This procedure is called to handle ReparentNotify events on
* top-level windows.
*
* Results:
* None.
*
* Side effects:
* Information gets updated in the WmInfo structure for the window.
*
*----------------------------------------------------------------------
*/
static void
* winPtr. */
{
int actualFormat;
unsigned long numItems, bytesAfter;
unsigned int dummy;
/*
* Identify the root window for winPtr. This is tricky because of
* virtual root window managers like tvtwm. If the window has a
* property named __SWM_ROOT or __WM_ROOT then this property gives
* the id for a virtual root window that should be used instead of
* the root window of the screen.
*/
&& (actualType == XA_WINDOW))
&& (actualType == XA_WINDOW))) {
} else if (wmTracing) {
printf("%s format %d numItems %ld\n",
"ReparentEvent got bogus VROOT property:", actualFormat,
numItems);
}
XFree((char *) virtualRootPtr);
}
if (wmTracing) {
printf("ReparentEvent: %s reparented to 0x%x, vRoot = 0x%x\n",
(unsigned int) vRoot);
}
/*
* Fetch correct geometry information for the new virtual root.
*/
/*
* If the window's new parent is the root window, then mark it as
* no longer reparented.
*/
return;
}
/*
* Search up the window hierarchy to find the ancestor of this
* window that is just below the (virtual) root. This is tricky
* because it's possible that things have changed since the event
* was generated so that the ancestry indicated by the event no
* longer exists. If this happens then an error will occur and
* we just discard the event (there will be a more up-to-date
* ReparentNotify event coming later).
*/
while (1) {
goto noReparent;
}
break;
}
}
if (!ComputeReparentGeometry(winPtr)) {
goto noReparent;
}
}
/*
*----------------------------------------------------------------------
*
* ComputeReparentGeometry --
*
* This procedure is invoked to recompute geometry information
* related to a reparented top-level window, such as the position
* and total size of the parent and the position within it of
* the top-level window.
*
* Results:
* The return value is 1 if everything completed successfully
* and 0 if an error occurred while querying information about
* winPtr's parents. In this case winPtr is marked as no longer
* being reparented.
*
* Side effects:
* Geometry information in winPtr and winPtr->wmPtr gets updated.
*
*----------------------------------------------------------------------
*/
static int
* is to be recomputed. */
{
unsigned int dummy;
if (status == 0) {
/*
* It appears that the reparented parent went away and
* no-one told us. Reset the window to indicate that
* it's not reparented.
*/
return 0;
}
/*
* Some tricky issues in updating wmPtr->x and wmPtr->y:
*
* 1. Don't update them if the event occurred because of something
* we did (i.e. WM_SYNC_PENDING and WM_MOVE_PENDING are both set).
* This is because window managers treat coords differently than Tk,
* and no two window managers are alike. If the window manager moved
* the window because we told it to, remember the coordinates we told
* it, not the ones it actually moved it to. This allows us to move
* the window back to the same coordinates later and get the same
* result. Without this check, windows can "walk" across the screen
* under some conditions.
*
* 2. Don't update wmPtr->x and wmPtr->y unless winPtr->changes.x
* or winPtr->changes.y has changed (otherwise a size change can
* spoof us into thinking that the position changed too and defeat
* the intent of (1) above.
*
* 3. Ignore size changes coming from the window system if we're
* about to change the size ourselves but haven't seen the event for
* it yet: our size change is supposed to take priority.
*/
wmPtr->x = x;
}
wmPtr->y = y;
}
}
if (wmTracing) {
printf("winPtr coords %d,%d, wmPtr coords %d,%d, offsets %d %d\n",
}
return 1;
}
/*
*----------------------------------------------------------------------
*
* 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 void
{
/*
* 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.
*/
}
if (wmTracing) {
}
/*
* Ignore the event if the window has never been mapped yet.
* Such an event occurs only in weird cases like changing the
* internal border width of a top-level window, which results
* in a synthetic Configure event. These events are not relevant
* to us, and if we process them confusion may result (e.g. we
* may conclude erroneously that the user repositioned or resized
* the window).
*/
}
if (wmTracing) {
}
if (wmTracing) {
}
}
}
/*
*----------------------------------------------------------------------
*
* 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 void
{
}
/*
* If the window isn't being positioned by its upper left corner
* then we have to move it as well.
*/
}
}
/*
*----------------------------------------------------------------------
*
* UpdateGeometryInfo --
*
* This procedure is invoked when a top-level window is first
* mapped, and also as a when-idle procedure, to bring the
* 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 void
{
unsigned long serial;
/*
* 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.
*/
} else {
}
if (width <= 0) {
width = 1;
}
} else {
}
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.
*/
} else {
x = wmPtr->x;
}
} 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.
*/
}
}
/*
* Reconfigure the window if it isn't already configured correctly.
* A few tricky points:
*
* 1. 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.
* 2. Can't just reconfigure always, because we may not get a
* ConfigureNotify event back if nothing changed, so
* WaitForConfigureNotify will hang a long time.
* 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 (wmTracing) {
printf("UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n",
}
if (wmTracing) {
}
} else {
return;
}
/*
* Wait for the configure operation to complete. Don't need to do
* this, however, if the window is about to be mapped: it will be
* taken care of elsewhere.
*/
}
}
/*
*--------------------------------------------------------------
*
* 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 void
{
hintsPtr = XAllocSizeHints();
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 PBaseSize
if (hintsPtr->base_width < 0) {
hintsPtr->base_width = 0;
}
if (hintsPtr->base_height < 0) {
hintsPtr->base_height = 0;
}
#endif
#if PBaseSize
#endif
#if PBaseSize
#endif
#if PBaseSize
#endif
#if PBaseSize
#endif
} else {
#if PBaseSize
hintsPtr->base_width = 0;
hintsPtr->base_height = 0;
#endif
}
#if PWinGravity
#endif
/*
* If the window isn't supposed to be resizable, then set the
* minimum and maximum dimensions to be the same.
*/
} else {
}
}
} else {
}
}
}
/*
*----------------------------------------------------------------------
*
* WaitForConfigureNotify --
*
* This procedure is invoked in order to synchronize with the
* window manager. It waits for a ConfigureNotify event to
* arrive, signalling that the window manager has seen an attempt
* on our part to move or resize a top-level window.
*
* Results:
* None.
*
* Side effects:
* Delays the execution of the process until a ConfigureNotify event
* arrives with serial number at least as great as serial. This
* is useful for two reasons:
*
* 1. It's important to distinguish ConfigureNotify events that are
* coming in response to a request we've made from those generated
* spontaneously by the user. The reason for this is that if the
* user resizes the window we take that as an order to ignore
* geometry requests coming from inside the window hierarchy. If
* we accidentally interpret a response to our request as a
* user-initiated action, the window will stop responding to
* new geometry requests. To make this distinction, (a) this
* procedure sets a flag for TopLevelEventProc to indicate that
* we're waiting to sync with the wm, and (b) all changes to
* the size of a top-level window are followed by calls to this
* procedure.
* 2. Races and confusion can come about if there are multiple
* operations outstanding at a time (e.g. two different resizes
* of the top-level window: it's hard to tell which of the
* ConfigureNotify events coming back is for which request).
* While waiting, all events covered by StructureNotifyMask are
* processed and all others are deferred.
*
*----------------------------------------------------------------------
*/
static void
* to see a ConfigureNotify. */
unsigned long serial; /* Serial number of resize request. Want to
* be sure wm has seen this. */
{
int gotConfig = 0;
/*
* One more tricky detail about this procedure. In some cases the
* window manager will decide to ignore a configure request (e.g.
* because it thinks the window is already in the right place).
* To avoid hanging in this situation, only wait for a few seconds,
* then give up.
*/
while (!gotConfig) {
&event);
if (wmTracing) {
printf("WaitForConfigureNotify giving up on %s\n",
}
break;
}
if (diff >= 0) {
gotConfig = 1;
}
}
if (wmTracing) {
printf("WaitForConfigureNotify finished with %s, serial %ld\n",
}
}
/*
*----------------------------------------------------------------------
*
* WaitForEvent --
*
* This procedure is used by WaitForConfigureNotify and
* WaitForMapNotify to wait for an event of a certain type
* to arrive.
*
* Results:
* Under normal conditions, TCL_OK is returned and an event for
* display and window that matches "mask" is stored in *eventPtr.
* This event has already been processed by Tk before this procedure
* returns. If a long time goes by with no event of the right type
* arriving, or if an error occurs while waiting for the event to
* arrive, then TCL_ERROR is returned.
*
* Side effects:
* While waiting for the desired event to occur, Configurenotify
* events for window are processed, as are all ReparentNotify events,
*
*----------------------------------------------------------------------
*/
static int
int type; /* Type of event that is wanted. */
{
#define TIMEOUT_MS 2000
/*
* Set up an event filter to select just the events we want, and
* a timer handler, then wait for events until we get the event
* we want or a timeout happens.
*/
info.foundEvent = 0;
(ClientData) &info);
while (1) {
if (info.foundEvent) {
break;
}
break;
}
}
if (info.foundEvent) {
return TCL_OK;
}
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* WaitRestrictProc --
*
* This procedure is a Tk_RestrictProc that is used to filter
* events while WaitForEvent is active.
*
* Results:
* Returns TK_PROCESS_EVENT if the right event is found. Also
* returns TK_PROCESS_EVENT if any ReparentNotify event is found
* for window or if the event is a ConfigureNotify for window.
* Otherwise returns TK_DEFER_EVENT.
*
* Side effects:
* An event may get stored in the area indicated by the caller
* of WaitForEvent.
*
*----------------------------------------------------------------------
*/
static Tk_RestrictAction
{
return TK_PROCESS_EVENT;
}
return TK_DEFER_EVENT;
}
return TK_PROCESS_EVENT;
}
return TK_PROCESS_EVENT;
}
return TK_DEFER_EVENT;
}
/*
*----------------------------------------------------------------------
*
* WaitTimeoutProc --
*
* This procedure is invoked as a timer handler when too much
* time elapses during a call to WaitForEvent. It sets a flag
* in a structure shared with WaitForEvent so that WaitForEvent
* knows that it should return.
*
* Results:
* None.
*
* Side effects:
* The timeout field gest set in the WaitRestrictInfo structure.
*
*----------------------------------------------------------------------
*/
static void
{
}
/*
*----------------------------------------------------------------------
*
* WaitForMapNotify --
*
* This procedure is invoked in order to synchronize with the
* window manager. It waits for the window's mapped state to
* reach the value given by mapped.
*
* Results:
* None.
*
* Side effects:
* Delays the execution of the process until winPtr becomes mapped
* or unmapped, depending on the "mapped" argument. This allows us
* to synchronize with the window manager, and allows us to
* identify changes in window size that come about when the window
* manager first starts managing the window (as opposed to those
* requested interactively by the user later). See the comments
* for WaitForConfigureNotify and WM_SYNC_PENDING. While waiting,
* all events covered by StructureNotifyMask are processed and all
* others are deferred.
*
*----------------------------------------------------------------------
*/
static void
* to see a particular mapping state. */
int mapped; /* If non-zero, wait for window to become
* mapped, otherwise wait for it to become
* unmapped. */
{
int code;
while (1) {
if (mapped) {
break;
}
break;
}
/*
* There are some bizarre situations in which the window
* manager can't respond or chooses not to (e.g. if we've
* got a grab set it can't respond). If this happens then
* just quit.
*/
if (wmTracing) {
}
break;
}
}
if (wmTracing) {
}
}
/*
*--------------------------------------------------------------
*
* UpdateHints --
*
* This procedure is called to update the window manager's
* hints information from the information in a WmInfo
* structure.
*
* Results:
* None.
*
* Side effects:
* Properties get changed for winPtr.
*
*--------------------------------------------------------------
*/
static void
{
return;
}
}
/*
*--------------------------------------------------------------
*
* ParseGeometry --
*
* This procedure parses a geometry string and updates
* information used to control the geometry of a top-level
* window.
*
* Results:
* A standard Tcl return value, plus an error message in
* interp->result if an error occurs.
*
* Side effects:
*
*--------------------------------------------------------------
*/
static int
char *string; /* String containing new geometry. Has the
* standard form "=wxh+x+y". */
* geometry is to be changed. */
{
char *end;
register char *p = string;
/*
* The leading "=" is optional.
*/
if (*p == '=') {
p++;
}
/*
* Parse the width and height, if they are present. Don't
* actually update any of the fields of wmPtr until we've
* successfully parsed the entire geometry string.
*/
x = wmPtr->x;
y = wmPtr->y;
p = end;
if (*p != 'x') {
goto error;
}
p++;
goto error;
}
p = end;
}
/*
* Parse the X and Y coordinates, if they are present.
*/
if (*p != '\0') {
if (*p == '-') {
flags |= WM_NEGATIVE_X;
} else if (*p != '+') {
goto error;
}
p = end;
if (*p == '-') {
flags |= WM_NEGATIVE_Y;
} else if (*p != '+') {
goto error;
}
if (*end != '\0') {
goto error;
}
/*
* Assume that the geometry information came from the user,
* unless an explicit source has been specified. Otherwise
* most window managers assume that the size hints were
* program-specified and they ignore them.
*/
}
}
/*
* Everything was parsed OK. Update the fields of *wmPtr and
* arrange for the appropriate information to be percolated out
* to the window manager at the next idle moment.
*/
wmPtr->x = x;
wmPtr->y = y;
flags |= WM_MOVE_PENDING;
}
return TCL_OK;
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* Tk_GetRootCoords --
*
* Given a token for a window, this procedure traces through the
* window's lineage to find the (virtual) root-window coordinates
* corresponding to point (0,0) in the window.
*
* Results:
* The locations pointed to by xPtr and yPtr are filled in with
* the root coordinates of the (0,0) point in tkwin. If a virtual
* root window is in effect for the window, then the coordinates
* in the virtual root are returned.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
int *xPtr; /* Where to store x-displacement of (0,0). */
int *yPtr; /* Where to store y-displacement of (0,0). */
{
int x, y;
/*
* Search back through this window's parents all the way to a
* top-level window, combining the offsets of each window within
* its parent.
*/
x = y = 0;
while (1) {
break;
}
}
*xPtr = x;
*yPtr = y;
}
/*
*----------------------------------------------------------------------
*
* Tk_CoordsToWindow --
*
* Given the (virtual) root coordinates of a point, this procedure
* returns the token for the top-most window covering that point,
* if there exists such a window in this application.
*
* Results:
* The return result is either a token for the window corresponding
* to rootX and rootY, or else NULL to indicate that there is no such
* window.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
* a virtual-root window manager is in use,
* these coordinates refer to the virtual
* root, not the real root. */
* used to identify the display. */
{
* far that contains point. */
int x, y; /* Coordinates in winPtr. */
/*
* Step 1: find any top-level window for the right screen.
*/
while (!Tk_IsTopLevel(tkwin)) {
}
/*
* Step 2: find the window in the actual root that contains the
* desired point. Special trick: if a virtual root window manager
* is in use, there may be windows in both the true root (e.g.
* pop-up menus) and in the virtual root; have to look in *both*
* places.
*/
panic("Tk_CoordsToWindow get False return from XTranslateCoordinates");
}
/*
* Step 3: if the window we've found so far (a child of the root)
* is the virtual root window, then look again to find the child of
* the virtual root.
*/
panic("Tk_CoordsToWindow get False return from XTranslateCoordinates");
}
}
return NULL;
}
break;
}
}
return NULL;
}
/*
* Step 4: work down through the hierarchy underneath this window.
* At each level, scan through all the children to find the highest
* one in the stacking order that contains the point. Then repeat
* the whole process on that child.
*/
x = rootX;
y = rootY;
while (1) {
continue;
}
}
}
break;
}
}
}
/*
*----------------------------------------------------------------------
*
* UpdateVRootGeometry --
*
* This procedure is called to update all the virtual root
* geometry information in wmPtr.
*
* Results:
* None.
*
* Side effects:
* The vRootX, vRootY, vRootWidth, and vRootHeight fields in
* wmPtr are filled with the most up-to-date information.
*
*----------------------------------------------------------------------
*/
static void
* updated. The wmPtr->vRoot field must
* be valid. */
{
int bd;
unsigned int dummy;
/*
* If this isn't a virtual-root window manager, just return information
* about the screen.
*/
return;
}
/*
* Refresh the virtual root information if it's out of date.
*/
(unsigned int *) &wmPtr->vRootWidth,
&dummy);
if (wmTracing) {
printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ",
}
if (status == 0) {
/*
* The virtual root is gone! Pretend that it never existed.
*/
goto noVRoot;
}
}
/*
*----------------------------------------------------------------------
*
* Tk_GetVRootGeometry --
*
* This procedure returns information about the virtual root
* window corresponding to a particular Tk window.
*
* Results:
* The values at xPtr, yPtr, widthPtr, and heightPtr are set
* with the offset and dimensions of the root window corresponding
* to tkwin. If tkwin is being managed by a virtual root window
* manager these values correspond to the virtual root window being
* used for tkwin; otherwise the offsets will be 0 and the
* dimensions will be those of the screen.
*
* Side effects:
* Vroot window information is refreshed if it is out of date.
*
*----------------------------------------------------------------------
*/
void
* queried. */
* here. */
{
/*
* Find the top-level window for tkwin, and locate the window manager
* information for that window.
*/
}
/*
* Make sure that the geometry information is up-to-date, then copy
* it out to the caller.
*/
}
}
/*
*----------------------------------------------------------------------
*
* Tk_MoveToplevelWindow --
*
* This procedure is called instead of Tk_MoveWindow to adjust
* the x-y location of a top-level window. It delays the actual
* move to a later time and keeps window-manager information
* up-to-date with the move
*
* Results:
* None.
*
* Side effects:
* The window is eventually moved so that its upper-left corner
* (actually, the upper-left corner of the window's decorative
* frame, if there is one) is at (x,y).
*
*----------------------------------------------------------------------
*/
void
Tk_MoveToplevelWindow(tkwin, x, y)
int x, y; /* New location for window (within
* parent). */
{
panic("Tk_MoveToplevelWindow called with non-toplevel window");
}
wmPtr->x = x;
wmPtr->y = y;
}
/*
* If the window has already been mapped, must bring its geometry
* up-to-date immediately, otherwise an event might arrive from the
* server that would overwrite wmPtr->x and wmPtr->y and lose the
* new position.
*/
}
}
}
/*
*----------------------------------------------------------------------
*
* UpdateWmProtocols --
*
* This procedure transfers the most up-to-date information about
* window manager protocols from the WmInfo structure to the actual
* property on the top-level window.
*
* Results:
* None.
*
* Side effects:
* The WM_PROTOCOLS property gets changed for wmPtr's window.
*
*----------------------------------------------------------------------
*/
static void
{
register ProtocolHandler *protPtr;
int count;
/*
* There are only two tricky parts here. First, there could be any
* number of atoms for the window, so count them and malloc an array
* to hold all of their atoms. Second, we *always* want to respond
* to the WM_DELETE_WINDOW protocol, even if no-one's officially asked.
*/
/* Empty loop body; we're just counting the handlers. */
}
"WM_DELETE_WINDOW");
arrayPtr[0] = deleteWindowAtom;
atomPtr++;
}
}
}
/*
*----------------------------------------------------------------------
*
* TkWmProtocolEventProc --
*
* This procedure is called by the Tk_HandleEvent whenever a
* ClientMessage event arrives whose type is "WM_PROTOCOLS".
* This procedure handles the message from the window manager
* in an appropriate fashion.
*
* Results:
* None.
*
* Side effects:
* Depends on what sort of handler, if any, was set up for the
* protocol.
*
*----------------------------------------------------------------------
*/
void
{
register ProtocolHandler *protPtr;
int result;
char *protocolName;
return;
}
/*
* Note: it's very important to retrieve the protocol name now,
* before invoking the command, even though the name won't be used
* until after the command returns. This is because the command
* could delete winPtr, making it impossible for us to use it
* later in the call to Tk_GetAtomName.
*/
"\" window manager protocol)");
}
return;
}
}
/*
* No handler was present for this protocol. If this is a
* WM_DELETE_WINDOW message then just destroy the window.
*/
}
}
/*
*----------------------------------------------------------------------
*
* TkWmRestackToplevel --
*
* This procedure restacks a top-level window.
*
* Results:
* None.
*
* Side effects:
* WinPtr gets restacked as specified by aboveBelow and otherPtr.
* This procedure doesn't return until the restack has taken
* effect and the ConfigureNotify event for it has been received.
*
*----------------------------------------------------------------------
*/
void
int aboveBelow; /* Gives relative position for restacking;
* must be Above or Below. */
* if NULL, then winPtr gets restacked
* above or below *all* siblings. */
{
unsigned int mask;
unsigned int numChildren;
int i;
int desiredIndex = 0; /* Initialized to stop gcc warnings. */
int ourIndex = 0; /* Initialized to stop gcc warnings. */
unsigned long serial;
int diff;
mask = CWStackMode;
}
/*
* Can't set stacking order properly until the window is on the
* screen (mapping it may give it a reparent window), so make sure
* it's on the screen.
*/
}
}
}
}
/*
* Before actually reconfiguring the window, see if it's already
* in the right place. If so then don't reconfigure it. The
* reason for this extra work is that some window managers will
* ignore the reconfigure request if the window is already in
* the right place, causing a long delay in WaitForConfigureNotify
* while it times out. Special note: if the window is almost in
* the right place, and the only windows between it and the right
* place aren't mapped, then we don't reconfigure it either, for
* the same reason.
*/
}
&children, &numChildren) != 0) {
/*
* Find where our window is in the stacking order, and
* compute the desired location in the stacking order.
*/
for (i = 0; i < numChildren; i++) {
ourIndex = i;
}
desiredIndex = i;
}
}
if (aboveBelow == Above) {
if (desiredIndex < ourIndex) {
desiredIndex += 1;
}
} else {
if (desiredIndex > ourIndex) {
desiredIndex -= 1;
}
}
} else {
if (aboveBelow == Above) {
} else {
desiredIndex = 0;
}
}
/*
* See if there are any mapped windows between where we are
* and where we want to be.
*/
while (desiredIndex != ourIndex) {
break;
}
if (desiredIndex < ourIndex) {
desiredIndex++;
} else {
desiredIndex--;
}
}
if (ourIndex == desiredIndex) {
return;
}
}
/*
* Reconfigure the window. This tricky because of two things:
* (a) Some window managers, like olvwm, insist that we raise
* or lower the toplevel window itself, as opposed to its
* decorative frame. Attempts to raise or lower the frame
* are ignored.
* (b) If the raise or lower is relative to a sibling, X will
* generate an error unless we work with the frames (the
* toplevels themselves aren't siblings).
* Fortunately, the procedure XReconfigureWMWindow is supposed
* to handle all of this stuff, so be careful to use it instead
* of XConfigureWindow.
*/
}
/*
* Wait for the reconfiguration to complete. If we don't wait, then
* the window may not restack for a while and the application might
* observe it before it has restacked. Waiting for the reconfiguration
* is tricky if winPtr has been reparented, since the window getting
* the event isn't one that Tk owns.
*/
} else {
while (1) {
break;
}
if (diff >= 0) {
break;
}
}
}
}
/*
*----------------------------------------------------------------------
*
* TkWmAddToColormapWindows --
*
* This procedure is called to add a given window to the
* WM_COLORMAP_WINDOWS property for its top-level, if it
* isn't already there. It is invoked by the Tk code that
* creates a new colormap, in order to make sure that colormap
* information is propagated to the window manager by default.
*
* Results:
* None.
*
* Side effects:
* WinPtr's window gets added to the WM_COLORMAP_WINDOWS
* property of its nearest top-level ancestor, unless the
* colormaps have been set explicitly with the
* "wm colormapwindows" command.
*
*----------------------------------------------------------------------
*/
void
* Should not be a top-level window. */
{
int count, i;
return;
}
/*
* Window is being deleted. Skip the whole operation.
*/
return;
}
break;
}
}
return;
}
/*
* Fetch the old value of the property.
*/
count = 0;
}
/*
* Make sure that the window isn't already in the list.
*/
for (i = 0; i < count; i++) {
return;
}
}
/*
* Make a new bigger array and use it to reset the property.
* Automatically add the toplevel itself as the last element
* of the list.
*/
for (i = 0; i < count; i++) {
}
if (count == 0) {
count++;
}
}
}
/*
*----------------------------------------------------------------------
*
* TkWmRemoveFromColormapWindows --
*
* This procedure is called to remove a given window from the
* WM_COLORMAP_WINDOWS property for its top-level. It is invoked
* when windows are deleted.
*
* Results:
* None.
*
* Side effects:
* WinPtr's window gets removed from the WM_COLORMAP_WINDOWS
* property of its nearest top-level ancestor, unless the
* top-level itself is being deleted too.
*
*----------------------------------------------------------------------
*/
void
* WM_COLORMAP_WINDOWS property for its
* top-level. Should not be a top-level
* window. */
{
int count, i, j;
/*
* Ancestors have been deleted, so skip the whole operation.
* Seems like this can't ever happen?
*/
return;
}
break;
}
}
/*
* Top-level is being deleted, so there's no need to cleanup
* the WM_COLORMAP_WINDOWS property.
*/
return;
}
/*
* Fetch the old value of the property.
*/
return;
}
/*
* Find the window and slide the following ones down to cover
* it up.
*/
for (i = 0; i < count; i++) {
for (j = i ; j < count-1; j++) {
}
break;
}
}
}
/*
*----------------------------------------------------------------------
*
* TkGetPointerCoords --
*
* Fetch the position of the mouse pointer.
*
* Results:
* *xPtr and *yPtr are filled in with the (virtual) root coordinates
* of the mouse pointer for tkwin's display. If the pointer isn't
* on tkwin's screen, then -1 values are returned for both
* coordinates. The argument tkwin must be a toplevel window.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
* on which lookup is to be done. */
{
unsigned int mask;
if (w == None) {
}
*xPtr = -1;
*yPtr = -1;
}
}
/*
*----------------------------------------------------------------------
*
* TkMakeWindow --
*
* Create an actual window system window object based on the
* current attributes of the specified TkWindow.
*
* Results:
* Returns the handle to the new window, or None on failure.
*
* Side effects:
* Creates a new X window.
*
*----------------------------------------------------------------------
*/
{
}
/*
*----------------------------------------------------------------------
*
* GetMaxSize --
*
* This procedure computes the current maxWidth and maxHeight
* values for a window, taking into account the possibility
* that they may be defaulted.
*
* Results:
* The values at *maxWidthPtr and *maxHeightPtr are filled
* in with the maximum allowable dimensions of wmPtr's window,
* in grid units. If no maximum has been specified for the
* window, then this procedure computes the largest sizes that
* will fit on the screen.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
* window. */
int *maxWidthPtr; /* Where to store the current maximum
* width of the window. */
int *maxHeightPtr; /* Where to store the current maximum
* height of the window. */
{
int tmp;
} else {
/*
* Must compute a default width. Fill up the display, leaving a
* bit of extra space for the window manager's borders.
*/
- 15;
/*
* Gridding is turned on; convert from pixels to grid units.
*/
}
*maxWidthPtr = tmp;
}
} else {
- 30;
}
*maxHeightPtr = tmp;
}
}