[comp.windows.x] problems with event handler in Motif 1.0.a

uwe@bredex.UUCP ( BREDEX GmbH) (04/12/90)

Dear xperts,

we have a problem using popup menus in Motif. The program attached
below should do the following:

- use a form widget with an included label widget

- add an event handler(ButtonPress) to the form and the label

- popup a different menu dependend on the widget the mouse button was
  pressed on

What actually happens is a bit strange:

if you use MB3 on the form, all is as expected
if you use MB3 on the label, the event handler is called, but the
widget id is that of the form
if you press MB2 and then MB3, you get the right widget id

We have RTFM, and we have UTSL, but we have found nothing to explain
this behavior. Is it documented somewhere, is it a bug in Motif or are
we just missing something?

BTW, this is Motif 1.0.a on a DECstation 3100, mwm running.

Thanks, Uwe

\|||/    Uwe Faustmann, Bredex GmbH
 o o     Braunschweig, West Germany
  >      uwe@bredex.uucp

===========================================================

#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>

#include <X11/Shell.h>


Display *display;
int *screen;
XtAppContext appContext;


void popupMenu (widget, menu, event)
Widget widget;
Widget menu;
XEvent *event;
{
    if (event->xbutton.button != Button3)
        return;

    XmMenuPosition(menu, event);
    XtManageChild (menu);

}


main (argc, argv)
int argc;
char *argv[];
{
    Widget shell;
    Widget form;
    Widget label;
    Widget menu1, menu2;
    Widget button1, button2;
    Arg args[10];
    Cardinal n;

    /*
     * Initialize the X Toolkit
     */

    XtToolkitInitialize ();

    /*
     * Create an application context
     */

    appContext = XtCreateApplicationContext ();

    /*
     * Open the display
     */

    display = XtOpenDisplay (appContext, (String) NULL,
			     "test", "Test",
			     (XrmOptionDescRec *) NULL, 0,
			     &argc, argv);

    if ( !display ) {
	printf ("Cannot open display\n");
	exit (1);
    }

    /*
     * Create an application shell
     */

    shell = XtAppCreateShell ("test", "Test",
			      applicationShellWidgetClass,
			      display,
			      (ArgList) NULL, 0);

    /*
     * Create a container
     */
    
    form = XmCreateForm (shell, "", NULL, 0);
    XtManageChild (form);

    menu1 = XmCreatePopupMenu (form, "Menu1", NULL, 0);
    button1 = XmCreatePushButton (menu1, "Button1", NULL, 0);
    XtManageChild (button1);
    XtAddEventHandler (form,
		       ButtonPressMask,
		       False,
		       popupMenu,
		       menu1);

    /*
     * Create a label inside the container
     */

    label = XmCreateLabel (form, "Label", NULL, 0);
    XtManageChild (label);

    menu2 = XmCreatePopupMenu (label, "Menu2", NULL, 0);
    button2 = XmCreatePushButton (menu2, "Button2", NULL, 0);
    XtManageChild (button2);
    XtAddEventHandler (label,
		       ButtonPressMask,
		       False,
		       popupMenu,
		       menu2);

    /*
     * get the show rolling
     */

    XtRealizeWidget (shell);

    XtAppMainLoop (appContext);
}

jeff@samna.UUCP (Jeff Barber) (04/14/90)

In article <792@bredex.UUCP> uwe@bredex.UUCP (Uwe Faustmann - BREDEX GmbH) writes:
>Dear xperts,
>
>we have a problem using popup menus in Motif. The program attached
>below should do the following:
>
>- use a form widget with an included label widget
>- add an event handler(ButtonPress) to the form and the label
>- popup a different menu dependend on the widget the mouse button was
>  pressed on
>What actually happens is a bit strange:
>
>if you use MB3 on the form, all is as expected
>if you use MB3 on the label, the event handler is called, but the
>widget id is that of the form
>if you press MB2 and then MB3, you get the right widget id

This happens on my system too (386 running ISC 386/ix w/Motif).
Here's what I figured out:

Someone/something is issuing an XGrabButton on Button3 on the window
associated with the Form widget.  I figured this out by implementing
my own XtMainLoop and printing out the events.  If you look at all
of the events caused by pressing the button inside the Label widget's
window, you'll notice that the first two events are Leave <LabelWindow>
and Enter <FormWindow> followed by the actual ButtonPress of Button1
delivered to the FormWindow.

If you press (and hold) Button1 or Button2 first, the passive Grab
is not activated and so the ButtonPress is delivered to the Label
Window (as you expect).

Anyway, that's what's happening - someone with source will have to
tell you where/why the grab call is being made and how to work around it.

Jeff

gabe@hpcvlx.cv.hp.com (Gabe Begeddov) (04/14/90)

    / hpcvlx:comp.windows.x / uwe@bredex.UUCP ( BREDEX GmbH) /  3:11 am  Apr 12, 1990 /
    Dear xperts,
    
    we have a problem using popup menus in Motif. The program attached
    below should do the following:
    
    - use a form widget with an included label widget
    
    - add an event handler(ButtonPress) to the form and the label
    
    - popup a different menu dependend on the widget the mouse button was
      pressed on
    
    What actually happens is a bit strange:
    
    if you use MB3 on the form, all is as expected
    if you use MB3 on the label, the event handler is called, but the
    widget id is that of the form
    if you press MB2 and then MB3, you get the right widget id
    
There is no support for nested popup menus that use the same button
in motif. The menus use a passive grab on the widget that they are 
popped up from. If an ancestor widget already has a passive grab for 
same event then it will be given to the ancestor widget by the server. 

When you press the MB2 first it activates an automatic grab which allows 
the MB3 press to be sent to the window it occurred in rather than the 
ancestor window that has a passive grab for it. If you were to press MB2
in the label and then move the pointer to another widget then this would
be the one that got the MB3! 

If you must use nested menus and don't need the grab functionality (i.e.
pop up this menu when the user presses the button in this widget or any of
it's descendants) then you could create the menus off of some non-related
widget and select for button events on the widgets that you are interested in
and then pop them up. If you do this you will also lose the ability to have
accelerators and mnemonics since these also use the grabs on the widget they 
are parented from. Another alternative is to use different buttons for the 
different menus. In Motif 1.0 you will be able to specify modifiers for the 
popup button and thereby have more possible menus without losing grab support.

    Thanks, Uwe
    
    \|||/    Uwe Faustmann, Bredex GmbH
     o o     Braunschweig, West Germany
      >      uwe@bredex.uucp
    
Gabe Beged-Dov
Interface Technology Operation
Hewlett Packard
Corvallis, Or (Home of the HP-UX New wave Desktop)