| [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #2978
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 2 - Low, e.g. a documentation error or undocumented side-effect |
Scope: | 3 - Applies to all machines and operating systems |
Subsystem: | Core Library |
Summary: | FL_DND_LEAVE not passed to handle() function |
Version: | 1.3.2 |
Created By: | jlp2 |
Assigned To: | AlbrechtS |
Fix Version: | 1.4.0 |
Fix Commit: | 6f7e1f4fb7e1277b4e28a15874db449cef2d6bfc |
Update Notification: | |
Trouble Report Files:
Trouble Report Comments:
|
#1 | jlp2 13:00 Sep 09, 2013 |
| Using the current FLTK 1.3.2 release the FL_DND_LEAVE event is never passed to an overridden handle() function.
I think this is because in the Fl::handle_() function in Fl.cxx, there is a return statement instead of a break statement. I attached a .diff file that shows the change I made to get it to work. Maybe someone who knows the code better could verify if this solution is correct and if there are similar bugs for the other cases (event types). | |
|
#2 | AlbrechtS 05:12 Sep 25, 2014 |
| Your widget must return 1 on FL_DND_ENTER to get FL_DND_DRAG and FL_DND_LEAVE events (related to the current drag operation). Note that you can get other (unrelated) FL_DND_LEAVE events due to how FLTK's event propagation works.
See the attached demo program dnd_leave.cxx for a working test case. This is derived from test/subwindow.cxx. Compile with
fltk-config --compile dnd_leave.cxx
then run the program and drag some text (from the input widgets or another program window) over the two widgets labeled "enterexit1" and "enterexit2" and watch the color changing to yellow and back to default when leaving the widget.
The events will be output to stdout if you run the program with an attached console, which will work with MinGW but maybe not with standard Windows programs compiled with MS VC++.
Please confirm that returning 1 on FL_DND_ENTER works for you.
If it does not work, please post a small and compileable example program (like dnd_leave.cxx) so that we can see the issue.
Note that this STR will be closed if we don't get a response within a reasonable time (about two weeks). | |
|
#3 | jlp2 05:53 Sep 25, 2014 |
| The test case you described and posted works for me, too. So maybe the problem does not occur for all widgets types. However, I still have the problem for Fl_Window widgets. I also attached a small example program. Just drag a something (like a file or text from another program) over the window. FL_DND_ENTER and FL_DND_DRAG are fired, FL_DND_LEAVE is not. | |
|
#4 | AlbrechtS 08:08 Sep 25, 2014 |
| Okay, I see. This needs more investigation, I'll take a look into it.
Thanks for posting the test program. | |
|
#5 | AlbrechtS 08:54 Sep 25, 2014 |
| I posted a new patch fl_dnd_leave_event_v2.diff against svn r 10336 - nothing else changed.
At a first glance and test, the patch makes FLTK send FL_DND_LEAVE events to windows, so this part seems okay. Thanks for the patch, BTW.
Meanwhile I used a modified test program with an embedded window (uploaded as dnd_leave_fl_window_v2.cxx), and this works as expected with the given patch. I can see the FL_DND_LEAVE events sent to the outer window in both cases: leaving the window to the inner window, or leaving it to the outside. So far, so good.
However, I'm still concerned whether there are side effects, because other widgets _got_ FL_DND_LEAVE events before. I'm not keen on sending even more FL_DND_LEAVE events to other widgets - or something like this.
I'm going to check this later... | |
|
#6 | AlbrechtS 03:01 Oct 17, 2014 |
| Looks like I made a step forward.
I found that your test program was missing an essential part: calling the handle() method of the base class. If I add this, I get the normal behavior that FL_DND_LEAVE is also sent to the derived window class.
Please see attached file dnd_leave_fl_window_handle.cxx which is a modified version of your test program dnd_leave_fl_window.cxx. This works as expected. Here is an example output:
1 - outer , Event: 20 - FL_DND_ENTER 2 - outer , Event: 21 - FL_DND_DRAG 3 - outer , Event: 22 - FL_DND_LEAVE 4 - outer , Event: 20 - FL_DND_ENTER 5 - outer , Event: 21 - FL_DND_DRAG 6 - outer , Event: 22 - FL_DND_LEAVE
Hence I believe now that your program is faulty, although it LOOKS strange that there is a return statement and not a break in fl_handle() as you pointed out.
From my current point of view this is not going to be "fixed" in FLTK 1.3.3 - if at all (I'm postponing further analysis). I reduced the priority to 2 (Low) for now.
Please check your original program and test if calling the handle() method of the base class (probably Fl_[Double_]Window::handle()) fixes the issue for you. Please don't forget to revert any changes in your FLTK code, if you were using a self-patched version. | |
|
#7 | jlp2 03:57 Oct 21, 2014 |
| Okay, great, I can confirm the code works when calling the handle() method of the base class.
My example was guided by yours, where "EnterExit::handle" doesn't call the handle method of the base class, too. So was your example also faulty? Should the call to the handle method of the base class be needed or not or for some specific widgets only? Maybe the correct way should be described more clearly in the docs. The docs for the "handle" method say "most of the time, you want to call the inherited handle() method in your overridden method so that you don't short-circuit events that you don't handle". It seems that either a) the the inherited handle() method should always be called even if the event is already handled by a component or b) the FLTK library code should be fixed (using the proposed patch or something similar). | |
|
#8 | AlbrechtS 08:00 Oct 22, 2014 |
| Faulty or not - hard to say. The docs are (maybe intentionally) not very clear, but they say "most of the time...". This is one case where you certainly need it. In windows it seems to be clear that you have to propagate all events to their child widgets. It may not be as obvious for FL_DND_*, but as it is now, it seems to be so.
In general there may be cases where you want to preclude events from being handled by the base class. One example is a kind of input filter in input widgets. If your derived widget doesn't want that particular key (character) to be entered (e.g. non-numeric keys in numeric input fields), then you would definitely not call the base class's handle(). However, in my opinion you must return 1, because your widget "consumed" the event (maybe by ringing a bell or other visual feedback). Hence it depends...
That said, I'll leave this STR open for further investigation whether the patch provided by you can or should be applied. Currently I can't say, so I won't apply it for now.
Anyway, I'm glad your problem is resolved, and thanks for the patch. | |
|
#9 | AlbrechtS 06:28 Nov 17, 2023 |
| Fixed in Git repository.
I decided to clarify the docs on event processing, particularly the phrase "Most of the time, you want to call the inherited handle() method ..." in Fl_Widget::handle().
Since the OP's issue (STR) has been resolved I'm closing this STR. | |
[ Return to Bugs & Features ]
|
| |