FLTK logo

Re: FLTK crashing after menu popup [General Use]

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: FLTK crashing after menu popup [General Use] Albrecht Schlosser Nov 01, 2016  
  On 01.11.2016 19:05 Will B wrote:
> On Tuesday, November 1, 2016 at 10:27:30 AM UTC-7, Greg Ercolano wrote:
>
>     On 11/01/16 07:58, Will B wrote:
>     > On Tuesday, November 1, 2016 at 3:50:54 AM UTC-7, MacArthur, Ian
>     (Leonardo, UK) wrote:
>     >     This looks like it works fine for me, does it work for you?
>     Does it do what you actually need to do?
>     >
>     > Yes, that worked, but in my example I'm doing the menu on a child
>     window.
>     > This is where the problem seems to be.  I'll modify your code and see
>     > if it works with a child window and will let you know.
>
>             Here's Ian's code modified to open the window in a child
>     window.
>
>     [...]
>
>
> Thanks for that.
>
> I guess I'm not making myself clear.  Oh well.
>
> What I'm trying to do is pop up an edit context menu when the user
> right-clicks an Fl_Input.  I tried subclassing Fl_Input, making an
> instance on a child window and popping up the menu within the handle()
> method, and it's still crashing as before.  I'm not sure if I should
> file an STP at this point because based on other users' posts it seems
> I'm doing something utterly unnatural, which I don't believe I am.

No, please don't file an STR. Your program is definitely _wrong_.

I used your program and tried to test. Once I got a crash I found a
stack depth < 500 which sounds silly for such a simple issue, right?

Let me first try to explain what is happening:

The reason is that your (test) program uses the wrong method
Fl::add_handler() and does not even try to check if

  (a) you have a push event
  (b) it is related to your widget
  (c) it might be some kind of recursion.

Once your program reaches the offending line "... miMain->popup(..)" it
starts a new nested event loop (with popup()). Then all following
unrecognized events with condition (Fl::event_button3() != 0) start
another popup menu etc. ...

My first thought was that Fl::event_button3() would not be reset during
event handling (note: the Fl::event_* state variables are only valid
during an event that is related to that particular state variable, i.e.
in this case a mouse move, push, or release event). But that seems not
to be the full problem. Anyway, here is my modified test program that
does not crash, but it doesn't do what you intended. It's just to show
what happens:

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Menu_Item.H>
#include <iostream>
#include <stdio.h>

/* handle right-click on child window */
int handleMiscEvents (int event)
{
     static int nn = 0;
     nn++; if (nn > 99999) nn = 0;
#if (1)
     printf("[%s:%d] event[%5d] = %3d, Fl::event_button3() = %d\n",
            __FUNCTION__, __LINE__, nn, event, Fl::event_button3());
     fflush(stdout);
#endif
     static int servicing_push = 0;

     // handle child window input controls right-click
     if (event == FL_PUSH && Fl::event_button3() != 0 && !servicing_push) {

        printf("*** GOT IT ! Servicing push ...***\n"); fflush(stdout);

        servicing_push = 1;

         // create context menu
         Fl_Menu_Item miMain[] = {
             {"Undo", 0, 0, 0, FL_MENU_DIVIDER},
             {"Cut", 0},
             {"Copy", 0},
             {"Paste", 0},
             {0}
         };

         // show context menu and return selected item, if any
         const Fl_Menu_Item* miRes = miMain->popup(Fl::event_x() + 14,
Fl::event_y() - 10);

         if (miRes != NULL) {

             const char* strRes = miRes->text;

             if (strRes != NULL) {
                 std::cout << strRes << std::endl;
             }
         }

        printf("*** Done ... servicing push.***\n"); fflush(stdout);
        servicing_push = 0;
         return 1;
     }

     return 0;
}


/* main program */
int main(int argc, char **argv)
{
     Fl::add_handler(handleMiscEvents);

     Fl_Window *window = new Fl_Window(1024, 740);

     window->end();
     window->show(argc, argv);

     Fl_Window *child = new Fl_Window(400, 400);
     child->box(FL_GTK_UP_BOX);

     Fl_Box *box = new Fl_Box(20, 40, 260, 100, "Right-click me");
     box->box(FL_BORDER_BOX);
     box->labelsize(18);
     box->labelfont(FL_BOLD + FL_ITALIC);

     child->add(box);

     window->add(child);
     child->show();

     return Fl::run();
}


When you run this program you may see lots of events that are NOT used
to popup() your menu. Particularly I didn't see FL_PUSH events. This is
likely caused by the fact that the events you're interested in are NOT
delivered to your handleMiscEvents() handler because they are used
internally and not "unrecognized". See the docs here:
<http://www.fltk.org/doc-1.3/group__fl__events.html#gae2d39bda7362e444afa41166c478b904>

I never saw the "GOT IT..." message, and most events shown have event
number 0.

So, now that we know this, what can be done?

The recommended solution is to use an Fl_Menu_Button as Greg and Ian
showed in their rewrites of your code. Note that you can "overlay" an
invisible menu button over another widget (Fl_Input or an entire group)
to pop up the menu you like wherever you want.

My intention was to test if this was a bug in FLTK, but it definitely
isn't. Your usage produces a recursion and eventually a stack overflow
or something like that.

Please try again if Greg's or Ian's solutions can help you. The main
point with Fl_Menu_Button is that you can define the reactive area,
whereas your global event handler would get all events anywhere in the
window (try to do a right-click anywhere in my modified test program and
you'll see).

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.