-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
1.1.5
-
generic
-
generic
Name: clC74495 Date: 04/22/98
Shell widgets do not display correctly running on PC, logged into
Unix platform using Exceed multiple windows with "native" window
manager.
In awt_Frame.c, in the function shellEH (the shell event handler), there is the
following large comment concerning calculation of border sizes for shells:
/* The insets were literally hardcoded in the MFramePeer.
But they are dependent upon both the window manager (WM)
and the hardware display. So, these are usually wrong.
This leads to problems with shell positioning and size.
Furthermore, there is not a published interface or way
to obtain from any given window manager the dimensions
of its decoration windows (i.e., borders and title bar).
So, given this problem in design, we must workaround.
Well, the first shell configure event we receive comes
from the window manager when it slightly repositions
our top level shell in incorporating its WM decorations.
We use the boolean wdata->fixInsets to tell us to trap
this event here. Then we get the shell (x,y) coordinates
using XtVaGetValues and also the coordinates of the WM
border using XGetWMNormalHints. The difference between
these gives us the actual pixel size of the WM title bar
and other borders. Iff these are different than the
values offered previously in MFramePeer, we correct the
insets (both our wdata structure and peer insets data).
N.B. (0) This works. But there is one functional caveat:
the frame.insets() function will usually return
the wrong values until AFTER the frame is shown.
It always did this before; it's just that now,
the values will become correct after rendering,
whereas before the values were never corrected.
(I believe this unavoidable given this design.)
(1) Note that we must/have to do this exactly once.
(2) The hardcoded values of MFramePeer (25 and 5)
are also utilized here and must be consistent.
(3) Assume top border (title bar) is one width,
and other three borders are another width.
This, however, could be easily reworked below. */
This unfortunately does not work with all window managers, since it makes the assumption
that the window manager will place the shell where XtSetArg() and/or XtVaSetValues says
to put it. But the window manager is under no such obligation, and can put the shell wherever
it wants.
I have created a small c program which illustrates this:
#include <Xm/Xm.h>
#include <Xm/PushB.h>
/* Prototype Callback function */
void pushed_fn(Widget, XtPointer, XmPushButtonCallbackStruct *);
main(int argc, char **argv)
{
Widget top_wid, button;
XtAppContext app;
Arg args[10];
int arg_count = 0;
Display *display = NULL;
XSizeHints hints;
long supplied;
top_wid = XtVaAppInitialize(&app, "Push", NULL, 0,
&argc, argv, NULL, NULL);
XtVaSetValues(top_wid, XmNx, 200, XmNy, 200, XmNwidth, 300, XmNheight, 300, N
ULL);
XtSetArg(args[arg_count], XmNx, 200); arg_count++;
XtSetArg(args[arg_count], XmNy, 200); arg_count++;
XtSetArg(args[arg_count], XmNwidth, 300); arg_count++;
XtSetArg(args[arg_count], XmNheight, 300); arg_count++;
button = XmCreatePushButton(top_wid, "Push_me", args, arg_count);
/* tell Xt to manage button */
XtManageChild(button);
/* attach fn to widget */
XtAddCallback(button, XmNactivateCallback, pushed_fn, NULL);
/* display widget hierarchy */
XtRealizeWidget(top_wid);
/* Try to get hints for shell */
XGetWMNormalHints(XtDisplay(top_wid), XtWindow(top_wid), &hints, &supplied);
printf("hints.x = %d, hints.y = %d\n", hints.x, hints.y);
/* enter processing loop */
XtAppMainLoop(app);
}
void pushed_fn(Widget w, XtPointer client_data,
XmPushButtonCallbackStruct *cbs)
{
long x = 0, y = 0;
XtVaGetValues(w, XmNx, &x, XmNy, &y, NULL);
printf("x = %d, y = %d\n", x, y);
}
=============end of c program
Note that I tell X to put the shell and the pushbutton at 200,200. This works fine when
I run when the Motif window manager (mwm). But try running this through Exceed using
multiple windows and the native (PC) window manager, and you get very different (and
much smaller) xy values for the location of the shell from XGetWMNormalHints (you can
also see visually that the shell is not in the same position as it is when mwm).
This makes the algorithm in shellEH() which calculates the border sizes for the widget
produce bizarre results when using the PC window manager.
You can also reproduce this problem with a small java program that
creates a Frame.
(Review ID: 28826)
======================================================================