home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / windows / x / 20728 < prev    next >
Encoding:
Text File  |  1993-01-04  |  4.7 KB  |  196 lines

  1. Xref: sparky comp.windows.x:20728 comp.windows.x.intrinsics:703 comp.windows.x.motif:8308
  2. Path: sparky!uunet!cs.utexas.edu!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!ursa!buzz
  3. From: buzz@bear.com (Buzz Moschetti)
  4. Newsgroups: comp.windows.x,comp.windows.x.intrinsics,comp.windows.x.motif
  5. Subject: X/Xt/Motif Event Interleaving?
  6. Message-ID: <BUZZ.93Jan4135708@lion.bear.com>
  7. Date: 4 Jan 93 18:57:08 GMT
  8. Sender: news@bear.com
  9. Reply-To: buzz@bear.com (Buzz Moschetti)
  10. Organization: Bear, Stearns & Co. - FAST
  11. Lines: 183
  12.  
  13. We are trying to create a very simple "drag-n-drop" type UI.  All widgets 
  14. that can be dragged or dropped on will live in the same container widget
  15. (xmFormWidgetClass).  Thus, we thought it would be possible to add event
  16. handlers to all child widgets as follows:
  17.  
  18.     XtAddEventHandler(widget,
  19.         EnterWindowMask | 
  20.         ButtonPressMask | ButtonReleaseMask | Button1MotionMask,
  21.               FALSE, my_event_proc, client_data);
  22.  
  23. Assume we have two button widgets.  Clicking on and dragging either widget
  24. correctly hits my_event_proc() with event->type set accordingly, likewise
  25. for entering the widgets.
  26.  
  27. What we thought would happen is while, say, widget 1 was dragged over
  28. widget 2, the latter's EnterNotify event would appear in the "stream" of
  29. widget 1's MotionNotify events, e.g.
  30.  
  31.     Dragging [w1]...
  32.     Dragging [w1]...
  33.     EnterNotify [w2]...
  34.     Dragging [w1]...
  35.  
  36. We do *not* see this behavior.  The problem is that widget 2 never gets
  37. the EnterNotify event until *after* the button is released, which is
  38. too late:
  39.  
  40.     Dragging [w1]...
  41.     Dragging [w1]...
  42.     ButtonRelease [w1]...
  43.     EnterNotify [w2]...
  44.  
  45. The setup *does* work if we drag widget 1 back over widget 1:
  46.  
  47.     Dragging [w1]...
  48.     Dragging [w1]...
  49.     EnterNotify [w1]...
  50.     Dragging [w1]...
  51.  
  52. Is what we're trying to do possible?  Is the problem that the clicked-on
  53. widget is grabbing all the events and forcing all others to be queued?
  54. We tried "splitting up" the event callbacks:
  55.  
  56.     XtAddEventHandler(widget, EnterWindowMask,
  57.               FALSE, my_event_proc, client_data);
  58.  
  59.     XtAddEventHandler(widget,
  60.         ButtonPressMask | ButtonReleaseMask | Button1MotionMask,
  61.               FALSE, OTHER_event_proc, client_data);
  62.  
  63. but this didn't work either.
  64.  
  65. Any help or direction is much appreciated.
  66.  
  67. P.S.  Here's a test program that demonstrates the problem.
  68.  
  69. /*
  70. cc -g -I/usr/include/Motif1.1 -I/usr/include/X11R4 tester.c -o tester -L /usr/lib/Motif1.1  -L /usr/lib/X11R4 -lXm -lXt -lX11
  71.  */
  72.  
  73.  
  74. #include <Xm/Form.h>
  75. #include <Xm/PushB.h>
  76.  
  77.  
  78. #define   DRAG_THRESHOLD   5
  79.  
  80. static void my_event_proc();
  81. static void my_event_proc2();
  82.  
  83.  
  84. Widget TopLevel;
  85. XtAppContext    AppContext;
  86.  
  87.  
  88. main(argc,argv)
  89. int     argc;
  90. char     *argv[];
  91. {
  92.       Widget form;
  93.       Widget w1, w2;
  94.  
  95.       TopLevel = XtAppInitialize(&AppContext, "xbaetest",
  96.                  NULL, 0, &argc, argv, NULL, NULL, 0);
  97.  
  98.  
  99.       form = XtVaCreateManagedWidget("main_form", xmFormWidgetClass, TopLevel,
  100.                    XmNwidth, 50, XmNheight, 50,
  101.                    NULL);
  102.  
  103.  
  104.       w1 = XtVaCreateManagedWidget("w1", xmPushButtonWidgetClass, form,
  105.                    XmNleftAttachment,  XmATTACH_FORM,
  106.                  NULL);
  107.  
  108.  
  109.       XtAddEventHandler(w1,
  110.             ButtonPressMask | ButtonReleaseMask | Button1MotionMask,
  111.             FALSE,my_event_proc, "w1");
  112.  
  113.       XtAddEventHandler(w1,
  114.             EnterWindowMask,
  115.             FALSE,my_event_proc2, "w1");
  116.  
  117.       
  118.  
  119.       w2 = XtVaCreateManagedWidget("w2", xmPushButtonWidgetClass, form,
  120.                    XmNrightAttachment,  XmATTACH_FORM,
  121.                  NULL);
  122.  
  123.       XtAddEventHandler(w2,
  124.             ButtonPressMask | ButtonReleaseMask | Button1MotionMask,
  125.             FALSE,my_event_proc, "w2");
  126.       XtAddEventHandler(w2,
  127.             EnterWindowMask,
  128.             FALSE,my_event_proc2, "w2");
  129.  
  130.  
  131.  
  132.       XtRealizeWidget(TopLevel);
  133.       XtAppMainLoop(AppContext);
  134.       return 0;
  135. }
  136.  
  137.  
  138.  
  139. static void
  140. my_event_proc(w, client_data, event)
  141. Widget w;
  142. XtPointer client_data;
  143. XEvent *event;
  144. {
  145.      static int drag_count = 0;
  146.  
  147.  
  148.      switch(event->type) {
  149.       default:
  150.        (void) printf("my_event_proc: type: %d\n", event->type);
  151.         break;
  152.  
  153.  
  154.       case ButtonPress:
  155.         (void) printf("ButtonPress %s\n", client_data);
  156.         break;
  157.  
  158.  
  159.       case ButtonRelease:
  160.         drag_count = 0;
  161.         (void) printf("ButtonRelease %s\n", client_data);
  162.         break;
  163.  
  164.  
  165.       case MotionNotify:
  166.         if(++drag_count <= DRAG_THRESHOLD) {
  167.           break;
  168.         }
  169.  
  170.         /*  Exceeded drag threshold; start changing!  Map the (x,y)
  171.          *  coords to actual floating point numbers as they would
  172.          *  appear on the graph:
  173.          */
  174.         /*    button_event->x, button_event->y, */
  175.         (void) printf("Dragging %s\n", client_data);
  176.         break;  /*       case MotionNotify: */
  177.       }
  178. }
  179.  
  180. static void
  181. my_event_proc2(w, client_data, event)
  182. Widget w;
  183. XtPointer client_data;
  184. XEvent *event;
  185. {
  186.      switch(event->type) {
  187.       default:
  188.        (void) printf("my_event_proc2: type: %d\n", event->type);
  189.         break;
  190.  
  191.       case EnterNotify:
  192.         (void) printf("EnterNotify %s\n", client_data);
  193.         break;
  194.       }
  195. }
  196.