can you help w/ a Xlib question?



Hi folks, sorry to bother this list but I figured this is where the 
X talent is these days.  I'm trying to make a little program that is
essentially a command line window manager, you give it xids and 
commands and it does them.  So far, I'm hung up on movement.  I'm
getting weird interaction with different window managers.  The 
easiest way to explain it is a demo.  So try this:

	. unpack this program into xmove.c
	. cc xmove.c -l/usr/X11R6/lib -lX11
	. xterm &
	. xterm &
	. xlsclients -l
	. a.out 0x1234 0x5678
	  >>> where the 0x1234 & 0x5678 are the window ids for the last
	  >>> two xterms in xlsclients' output

	  then give it x y coords, those are deltas. Like so

	  $ a.out 0x280000e 0x2c0000e
	  10 10	# move to over, 10 down
	  0 -50	# move up 50
	  ^D

This works well under ctwm but not under redhat's default window manager.
It's a tiny program, can anyone tell me how this should be done?

By the way, as motivation, this is part of a package I'm doing that lets
you have N xterms (whatever) up and send input to all of them at once.
It's a rewrite of the Sun sparccluster I console interface that I did 
about 6 years ago and it's handy as hell for stress testing and sys admin
stuff.  I'll post it as soon as I can get this part to work.

Thanks,

--lm

/*
 *  xmove.c - given a set of window ids, perform moves on them.
 *
 * This gets screwed up by interaction with the window manager. 
 * As it stands right now, it works exactly under ctwm but off
 * by about 20 pixels or so with fvwm-2 (or whatever is the
 * default for redhat).
 *
 * Why should I care, you ask?  I'm trying to make an X program that
 * clusters a group of x windows (xterms, actually) such that when
 * my window is moved, I move the other windows as well.
 *
 * I have this vague feeling that what I really want to do is reparent
 * the xterms under my window but then I couldn't use the window manager
 * to move the xterms by themselves.  I'm open to advice.
 *
 * Send comments to mcvoy@ibm.net.
 *
 * Build:
 *	cc xmove.c -L/usr/X11R6/lib -lX11
 * Run:
 *	xterm &
 *	xterm &		# just one was enough but 2 is more fun :-)
 *	xlsclients -l	# grab the last two window ids
 *	a.out 0x<id #1> 0x<id #2>
 *	10 10		# move it right/down
 *	-10 -10		# move 'em back
 */
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>

Window	xids[100];
int	n;

int
main(int ac, char **av)
{
	char	buf[100];
	int	i, x, y;

	for (i = 1; i < ac; ++i) {
		sscanf(av[i], "0x%lx", &xids[i-1]);
		n++;
	}
	while (fgets(buf, sizeof(buf), stdin)) {
		sscanf(buf, "%d %d", &x, &y);
		move(ac, av, x, y);
	}
}

move(int ac, char **av, int x, int y)
{
	int	i;
	Display	*d;
	static int border;
	XWindowAttributes wa;

	printf("move(%d, %d)\n", x ,y);
	if (border) {
		y += border;
		x += border;
	}
	d = XOpenDisplay(getenv("DISPLAY"));
	for (i = 0; i < n; ++i) {
		Window	r, p, gp, *c;
		int	num;

		/*
		 * The idea here was to look up the tree
		 * until we get to the one that the window manager is 
		 * managing.  Then get it's coords and move accordingly.
		 */
		XQueryTree(d, xids[i], &r, &p, &c, &num);
		/* XXX - free children */
		gp = p;
		do {
			p = gp;
			XQueryTree(d, p, &r, &gp, &c, &num);
			/* XXX - free children */
			XGetWindowAttributes(d, p, &wa);
			if (!border && wa.border_width) {
				border = wa.border_width;
				printf("Border: %d\n", border);
				y += border;
				x += border;
			}
		} while (gp != r);
		XMoveWindow(d, p, wa.x + x, wa.y + y);
	}
	XSync(d, 0);
	XCloseDisplay(d);
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]