Re: Initial window placement



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]