Re: Initial window placement
- From: "Matthias Clasen" <matthiasc poet de>
- To: <wm-spec-list gnome org>
- Subject: Re: Initial window placement
- Date: Wed, 22 Aug 2001 00:10:07 +0200
The two utilities below allow even more thorough testing of window managers
behaviour wrt to resizing/moving and gravity. hints.c lets you change
WM_NORMAL_HINTS of arbitrary windows from the cmdline,
configure.c allows to change a windows position, size and borderwidth.
Matthias
/* hints.c: Set ICCCM size hints from the cmdline arguments
-min, -max, -inc, -base, -aspect, -gravity
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
static
Window TryChildren (dpy, win, WM_STATE)
Display *dpy;
Window win;
Atom WM_STATE;
{
Window root, parent;
Window *children;
unsigned int nchildren;
unsigned int i;
Atom type = None;
int format;
unsigned long nitems, after;
unsigned char *data;
Window inf = 0;
if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren))
return 0;
for (i = 0; !inf && (i < nchildren); i++) {
XGetWindowProperty(dpy, children[i], WM_STATE, 0, 0, False,
AnyPropertyType, &type, &format, &nitems,
&after, &data);
if (type)
inf = children[i];
}
for (i = 0; !inf && (i < nchildren); i++)
inf = TryChildren(dpy, children[i], WM_STATE);
if (children) XFree((char *)children);
return inf;
}
static
Window XmuClientWindow (dpy, win)
Display *dpy;
Window win;
{
Atom wm_state;
Atom type = None;
int format;
unsigned long nitems, after;
unsigned char *data;
Window inf;
wm_state = XInternAtom (dpy, "WM_STATE", True);
if (!wm_state)
return win;
XGetWindowProperty (dpy, win, wm_state, 0, 0, False, AnyPropertyType,
&type, &format, &nitems, &after, &data);
if (type)
return win;
inf = TryChildren(dpy, win, wm_state);
if (!inf)
inf = win;
return inf;
}
int x_error (Display *dpy, XErrorEvent *e)
{
char buf[1000];
XGetErrorText (dpy, e->error_code, buf, 1000);
printf ("X Error:\n\tserial %i\n\terror code %i\n\trequest code
%i\n\tminor code %i\n\t resource id %i\n\terror text %s\n",
e->serial,
e->error_code,
e->request_code,
e->minor_code,
e->resourceid,
buf);
}
Window
select_window (Display *dpy)
{
int status;
Cursor cursor;
XEvent event;
Window win = None;
Window root = DefaultRootWindow (dpy);
int buttons = 0;
/* Make the target cursor */
cursor = XCreateFontCursor (dpy, XC_crosshair);
/* Grab the pointer using target cursor, letting it room all over */
status = XGrabPointer (dpy, root, False,
ButtonPressMask|ButtonReleaseMask, GrabModeSync,
GrabModeAsync, root, cursor, CurrentTime);
if (status != GrabSuccess)
{
fprintf (stderr, "Can't grab the mouse.\n");
exit (1);
}
/* Let the user select a window... */
while ((win == None) || (buttons != 0))
{
/* allow one more event */
XAllowEvents (dpy, SyncPointer, CurrentTime);
XWindowEvent (dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
switch (event.type)
{
case ButtonPress:
if (win == None)
{
win = event.xbutton.subwindow; /* window selected */
}
buttons++;
break;
case ButtonRelease:
if (buttons > 0) /* there may have been some down before we started
*/
buttons--;
break;
}
}
XUngrabPointer (dpy, CurrentTime); /* Done with pointer */
return win;
}
int
main (int argc, char **argv)
{
Display *dpy;
int i, scr, dummyi;
unsigned int dummy;
Window root, win = None;
XSizeHints h;
dpy = XOpenDisplay (NULL);
scr = DefaultScreen (dpy);
root = RootWindow (dpy, scr);
XSetErrorHandler (x_error);
h.flags = 0;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "-id") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
sscanf (argv[++i], "0x%lx", &win);
}
else if (strcmp(argv[i], "-min") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
h.flags |= PMinSize;
h.min_width = atoi(argv[++i]);
h.min_height = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-max") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
h.flags |= PMaxSize;
h.max_width = atoi(argv[++i]);
h.max_height = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-inc") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
h.flags |= PResizeInc;
h.width_inc = atoi(argv[++i]);
h.height_inc = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-base") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
h.flags |= PBaseSize;
h.base_width = atoi(argv[++i]);
h.base_height = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-aspect") == 0)
{
if (i + 4 >= argc)
{
fprintf (stderr, "option requires 4 arguments: `%s'\n", argv[i]);
exit (1);
}
h.flags |= PAspect;
h.min_aspect.x = atoi(argv[++i]);
h.min_aspect.y = atoi(argv[++i]);
h.max_aspect.x = atoi(argv[++i]);
h.max_aspect.y = atoi(argv[++i]);
}
else if (strcmp(argv[i], "-gravity") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
char *g = argv[++i];
h.flags |= PWinGravity;
if (!strcasecmp (g, "center"))
h.win_gravity = CenterGravity;
else if (!strcasecmp (g, "static"))
h.win_gravity = StaticGravity;
else if (!strcasecmp (g, "north"))
h.win_gravity = NorthGravity;
else if (!strcasecmp (g, "northeast"))
h.win_gravity = NorthEastGravity;
else if (!strcasecmp (g, "east"))
h.win_gravity = EastGravity;
else if (!strcasecmp (g, "SouthEast"))
h.win_gravity = SouthEastGravity;
else if (!strcasecmp (g, "south"))
h.win_gravity = SouthGravity;
else if (!strcasecmp (g, "southwest"))
h.win_gravity = SouthWestGravity;
else if (!strcasecmp (g, "west"))
h.win_gravity = WestGravity;
else
h.win_gravity = NorthWestGravity;
}
else
{
fprintf (stderr, "unknown option: `%s'\n", argv[i]);
exit (1);
}
}
if (win == None)
{
win = select_window (dpy);
}
if (win == None)
{
XBell (dpy, 50);
exit (1);
}
if (XGetGeometry (dpy, win, &root, &dummyi, &dummyi,
&dummy, &dummy, &dummy, &dummy) &&
win != root)
{
win = XmuClientWindow (dpy, win);
}
XSetWMNormalHints (dpy, win, &h);
XCloseDisplay (dpy);
return 0;
}
/* configure.c: Configure a window from the cmdline
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
static
Window TryChildren (dpy, win, WM_STATE)
Display *dpy;
Window win;
Atom WM_STATE;
{
Window root, parent;
Window *children;
unsigned int nchildren;
unsigned int i;
Atom type = None;
int format;
unsigned long nitems, after;
unsigned char *data;
Window inf = 0;
if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren))
return 0;
for (i = 0; !inf && (i < nchildren); i++) {
XGetWindowProperty(dpy, children[i], WM_STATE, 0, 0, False,
AnyPropertyType, &type, &format, &nitems,
&after, &data);
if (type)
inf = children[i];
}
for (i = 0; !inf && (i < nchildren); i++)
inf = TryChildren(dpy, children[i], WM_STATE);
if (children) XFree((char *)children);
return inf;
}
static
Window XmuClientWindow (dpy, win)
Display *dpy;
Window win;
{
Atom wm_state;
Atom type = None;
int format;
unsigned long nitems, after;
unsigned char *data;
Window inf;
wm_state = XInternAtom (dpy, "WM_STATE", True);
if (!wm_state)
return win;
XGetWindowProperty (dpy, win, wm_state, 0, 0, False, AnyPropertyType,
&type, &format, &nitems, &after, &data);
if (type)
return win;
inf = TryChildren(dpy, win, wm_state);
if (!inf)
inf = win;
return inf;
}
int x_error (Display *dpy, XErrorEvent *e)
{
char buf[1000];
XGetErrorText (dpy, e->error_code, buf, 1000);
printf ("X Error:\n\tserial %i\n\terror code %i\n\trequest code
%i\n\tminor code %i\n\t resource id %i\n\terror text %s\n",
e->serial,
e->error_code,
e->request_code,
e->minor_code,
e->resourceid,
buf);
}
Window
select_window (Display *dpy)
{
int status;
Cursor cursor;
XEvent event;
Window win = None;
Window root = DefaultRootWindow (dpy);
int buttons = 0;
/* Make the target cursor */
cursor = XCreateFontCursor (dpy, XC_crosshair);
/* Grab the pointer using target cursor, letting it room all over */
status = XGrabPointer (dpy, root, False,
ButtonPressMask|ButtonReleaseMask, GrabModeSync,
GrabModeAsync, root, cursor, CurrentTime);
if (status != GrabSuccess)
{
fprintf (stderr, "Can't grab the mouse.\n");
exit (1);
}
/* Let the user select a window... */
while ((win == None) || (buttons != 0))
{
/* allow one more event */
XAllowEvents (dpy, SyncPointer, CurrentTime);
XWindowEvent (dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
switch (event.type)
{
case ButtonPress:
if (win == None)
{
win = event.xbutton.subwindow; /* window selected */
}
buttons++;
break;
case ButtonRelease:
if (buttons > 0) /* there may have been some down before we started
*/
buttons--;
break;
}
}
XUngrabPointer (dpy, CurrentTime); /* Done with pointer */
return win;
}
int
main (int argc, char **argv)
{
Display *dpy;
int i, x, y, w, h, scr, dummyi;
unsigned int dummy, mask;
XWindowChanges ch;
Window root, win = None;
dpy = XOpenDisplay (NULL);
scr = DefaultScreen (dpy);
root = RootWindow (dpy, scr);
XSetErrorHandler (x_error);
mask = 0;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "-x") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWX;
ch.x = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-y") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWY;
ch.y = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-pos") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWX | CWY;
ch.x = atoi (argv[++i]);
ch.y = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-w") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWWidth;
ch.width = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-h") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWHeight;
ch.height = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-size") == 0)
{
if (i + 2 >= argc)
{
fprintf (stderr, "option requires 2 arguments: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWWidth | CWHeight;
ch.width = atoi (argv[++i]);
ch.height = atoi (argv[++i]);
}
else if (strcmp (argv[i], "-border") == 0)
{
if (i + 1 >= argc)
{
fprintf (stderr, "option requires argument: `%s'\n", argv[i]);
exit (1);
}
mask = mask | CWBorderWidth;
ch.border_width = atoi (argv[++i]);
}
else
{
fprintf (stderr, "unknown option: `%s'\n", argv[i]);
exit (1);
}
}
if (win == None)
{
win = select_window (dpy);
}
if (win == None)
{
XBell (dpy, 50);
exit (1);
}
if (XGetGeometry (dpy, win, &root, &dummyi, &dummyi,
&dummy, &dummy, &dummy, &dummy) &&
win != root)
{
win = XmuClientWindow (dpy, win);
}
if (mask != 0)
{
XConfigureWindow (dpy, win, mask, &ch);
}
XCloseDisplay (dpy);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]