[comp.windows.x.motif] Querying/Managing the size/position of windows

db3l@ibm.com (David Bolen) (10/04/90)

I'm working on a project where I have a need to track changes in the position
and size of windows I create, and at certain times, reposition those windows
the way I want.  However, I'm having difficulty both in obtaining accurate
information about the windows as they change size and position, and being
able to reliably modify that size and position.  I'd like to know if anyone
can shed some light on what is happening and/or suggest any solutions.  This
post is somewhat long (I've separated each question with Ctrl-L for readers
that handle this), but I would really appreciate any help.

In my simplest test, I have a single top-level window for my application.
This consists of an application shell, a MainWindow widget and a DrawingArea
widget which is assigned as the work area for the MainWindow.  What I want is
to be able to determine at any given point in time, just where my drawing area
is located and what size it is.


Question 1:
   How do I keep track of where the window's origin is?

I originally tried using XtGetValues for resources XmNx and XmNy of my drawing
area (being a "good" Motif programmer I wanted to use the Motif resources), but
they weren't always up to date.  For example, if I resized the upper edge of
my window upwards, thus moving the origin of the window relative to the
screen, the XmNx and XmNy resources didn't change.  It was only after I
actually moved the window that they were updated to indicate its new position.
I ended up using XTranslateCoordinates of (0,0) in the drawing area to the
root of the screen in order to obtain up to date information on its position,
but I'd appreciate hearing if there is a better (or more proper) method.


Question 2:
   How do I keep track of the current window size, and be able to query
   that size when I wish to?

This is one I am still struggling with - depending on whether I query the
window directly or use a callback or event handler, I get different information
on the current size of the window, and I need a reliable way to get current
information.

For example, let's say that I establish a handler for ConfigureNotify events
(event_mask StructureNotifyMask).  I use a configure event rather than the
resize callback provided by the drawing area because I like having a single
handler for both size and position changes.  When I resize the window, my
configure event handler runs, and the data in the XConfigureEvent structure
it is passed contains the proper new width and height for the window.  However,
if inside the same function I issue a XGetGeometry or XGetWindowAttributes
call, the width and height I get back are the previous width and height and
not the new information.  Since a ConfigureNotify should indicate changes
that have already occurred, why don't the functions return the same information
I am given as part of the configure event.

The reason this arises, is that I compute scaling factors according to the
window size, and the computation routine is called from several places, only
one of which is the configure event handler.  So, to make things easier,
the scaling is computed from the results of an XGetGeometry call rather than
requiring the caller to supply the window size, but in the case of being
called from the configure event handler, XGetGeometry returns incorrect
information, and thus the scaling factors are not correctly changed for the
new window size.

What I need is a valid method for determining up to date information on the
size of the window.  By the time my configure event handler is called, the
window is already at the new size on the screen, so someone must know what
the "current" size is.  Is there anyway for me to query it?


Question 3:
   How do I reliably change a window's size and/or position.

I realize that in general, any geometry changes are a coordinated effort
within a particular window tree, and are subject to rules set forth by the
window manager, but I don't think any of those restrictions should be
affecting what I am trying (and not quite succeeding) to do.

Let's say that I create a PushButtonGadget within my drawing area.  Now,
at some point I want to reposition and resize that pushbutton.  So I issue
an XtSetValues for the XmNx, XmNy, XmNwidth and XmNheight resources to what
I desire.  From what I can see in the documentation, PushButtonGadgets do
not have any particular constraints on how they may be positioned, and a
DrawingArea does not place additional constraints on its children.  I have
also specified XmNallowShellResize as TRUE for the outer application shell,
so it shouldn't force any restrictions either.

My problem is that the pushbutton does not always resize to the new
position.  Most of the time it will, but sometimes it will blink and yet
stay in its current location.  Empirically it seems that the larger the
change I am attempting to make the more likely it will fail, for whatever
that is worth.

What's most confusing is that if I then attempt to resize the pushbutton
again (perhaps with a difference of only a pixel or two in size), it will
succeed.  I should also mention that during this resizing process, the
parent DrawingArea may also be being resized and/or repositioned.

What I'm trying to find out is why this might be happening and if there is
a way I can adjust the position reliably.  Maybe I'm missing a constraint
on the position and size of the pushbutton that is creating this effect.


If anyone has any ideas of what is happening or how to solve any of my
questions, please let me know.  Thanks.

-- David
--
/-----------------------------------------------------------------------\      
 \                             David Bolen                             /
  |    Laboratory Automation, IBM Thomas J. Watson Research Center    |
 /              P.O. Box 218, Yorktown Heights, NY  10598              \
| - - - - - - - - - - - -  M i t h r a n d i r  - - - - - - - - - - - - |
| Internet : db3l@ibm.com                    | Bitnet : db3l@yktvmv     |
| Usenet   : uunet!bywater!arnor!larios!db3l | Phone  : (914) 945-1940  |
\-----------------------------------------------------------------------/