[comp.windows.x] YAXT

clyde@ut-ngp.UUCP (04/02/87)

Here is something I put together to pull in windows which were off screen.
This usually happens when you iconify a window too close to the edge of
the screen.  So this program will pull them back to a visible place on the
display.

--------------- CUT HERE ---------------------
/*
 *	xfixwindows - a program to find any off-screen windows and
 *	move them sufficently on-screen to be grabbed with the mouse.
 *
 *	Compilation info:
 *		cc -o xfixwindows -O xfixwindows.c -lX
 *
 *	Clyde Hoover
 *	Computation Center, University of Texas at Austin
 *	March 1987
 */
#include	<stdio.h>
#include	<X/Xlib.h>

#define fatal(M) { perror(M); exit(1); }
#define emptystack()	StackTop = 0
#define	push(W)		WindowStack[++StackTop] = (W)

int	StackTop = 0;		/* Top of window display stack */
Window	WindowStack[64];	/* The window display stack */
int	silent = 0;		/* Mode */

main(argc, argv)
int	argc;
char	*argv[];
{
	char	*display_name = 0;	/* Server name */
	Display	*d;		/* X server */
	int	nchildren;	/* # of windows */
	Window	parent_win,	/* Parent of root window */
		*child_list;	/* List of child windows */
	WindowInfo	win_info,	/* Window info */
			root_info;	/* Root window info */
	extern char *getenv();

	display_name = getenv("DISPLAY");
	if ((d = XOpenDisplay(display_name)) == NULL)
		fatal("Can't open display");

	/* Get root window sizing info */
	if (XQueryWindow(RootWindow, &root_info) == 0)
		fatal("Can't get root window info");

	/* get a list of children of the root window */
	if (XQueryTree(RootWindow, &parent_win, &nchildren, &child_list) == 0)
		fatal("Can't query window tree");

	/* scan list */
	for ( ; nchildren-- > 0; child_list++) {
		if (XQueryWindow(*child_list, &win_info) == 0)
			continue;
		/*
		 * Check & fix the immediate root child window
		 */
		fixwindow(*child_list, &win_info,
			root_info.width, root_info.height);
		/*
		 * Follow the chain of associated windows until the end
		 * or until a previously seen window is found.
		 */
		emptystack();
		push(*child_list);
		while (win_info.assoc_wind) {
			if (instack(win_info.assoc_wind))
				break;
			push(win_info.assoc_wind);
			if (XQueryWindow(win_info.assoc_wind, &win_info))
				fixwindow(win_info.assoc_wind,
					&win_info, root_info.width,
					root_info.height);
			else
				break;
		}
	}
	exit(0);
}

/*
 *	instack - look for the given window in window display stack 
 *
 *	Returns: 1 if found
 *		 0 if not
 */
instack(w)
Window	w;		/* Window to look for */
{
	register int i = StackTop;	/* Temp */

	while (i)
		if (WindowStack[i--] == w) return(1);
	return(0);
}

/*
 *	fixwindow - 'fix' position of this window if needed
 */
fixwindow(id, info, maxw, maxh)
Window	id;		/* Window to 'fix' */
WindowInfo	*info;	/* Window information block */
int	maxw,		/* X limit for display */
	maxh;		/* Y limit for display */
{
	int	newx,		/* New X window coordinate */
		newy;		/* New Y window coordinate */
	int	fudge = 16;	/* Window boundary fudge factor */

	/*
 	 * See if this is a type of window that we don't care about
	 */
	if (info->type == IsUnmapped ||
	    info->mapped == IsInvisible ||
	    info->type == IsTransparent)
		return;	

	newx = info->x;
	newy = info->y;
	/*
	 * The 'fudge' factor here is how much of the outer (right & bottom)
	 * edge of the display can't be accessed by the cursor, since
	 * its hot-spot can be anywhere.  We would really like to know what
	 * the cursor shape is and where its hotspot is in order to make
	 * this fudge factor correct, but no such luck - so we guess.
	 */
	/*
	 * Make X origin within the display
	 */
	if (info->x < 0 || info->x > (maxw - fudge)) {
		if (info->x < 0) newx = 0;
		else newx = maxw - info->width;
	}
	/*
	 * Make Y origin within the display
	 */
	if (info->y < 0 || info->y > (maxh - fudge)) {
		if (info->y < 0) newy = 0;
		else newy = maxh - info->height;
	}
	if (newx == info->x && newy == info->y)
		return;

	if (!silent) {
		char	*wstate, *wtype, *win_name;	/* Temp */

		XFetchName(id, &win_name);
		switch(info->mapped) {
		case IsMapped:		wstate = "mapped"; break;
		case IsUnmapped:	wstate = "unmapped"; break;
		case IsInvisible:	wstate = "invisible"; break;
		default:		wstate = "unknown map"; break;
		}
		switch(info->type) {
		case IsTransparent:	wtype = "transparent"; break;
		case IsOpaque:		wtype = "opaque"; break;
		case IsIcon:		wtype = "icon"; break;
		default:		wtype = "unknown type"; break;
		}
		printf("Window %d \"%s\" [%s %s] at %d,%d -- moving to %d,%d\n",
			id, win_name, wstate, wtype,
			info->x, info->y, newx, newy);
	}
	XMoveWindow(id, newx, newy);	/* Move the window */
}
---- end ----
-- 
Shouter-To-Dead-Parrots @ Univ. of Texas Computation Center; Austin, Texas  
	clyde@ngp.cc.utexas.edu; ...!ut-sally!ut-ngp!clyde
"It's a sort of a threat, you see.  I've never been very good at them
myself, but I've told they can be very effective."