|
|
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 ] | |
|
| |