Fl_Output disable drag-n-drop

32 views
Skip to first unread message

Rob McDonald

unread,
May 2, 2016, 1:28:53 AM5/2/16
to fltk.general

I have derived a class from Fl_Group that can receive drag-n-drop payloads.

Inside that group, among other widgets, I have an Fl_Output.

On OSX, the Fl_Output widget sometimes intercepts the drop payload, causes the computer to beep, and sometimes prevents the payload from being delivered to the group.  Other times, it passes on through fine.

On other platforms, it doesn't seem to do this.

Similarly, in another portion of my program, I have an Fl_Input that similarly intercepts the dropped payload.  On OSX, it always prevents the payload from being delivered.  On Windows, the payload string briefly appears in the Fl_Input box until my program refreshes it.  The payload is then successfully delivered.

Is there a way to disable Fl_Input and Fl_Output receipt of dropped payloads without deriving a new class?  Or, if that is the best way, what do you suggest?

Rob

Albrecht Schlosser

unread,
May 2, 2016, 5:53:45 AM5/2/16
to fltkg...@googlegroups.com
On 02.05.2016 07:28 Rob McDonald wrote:
>
> I have derived a class from Fl_Group that can receive drag-n-drop payloads.
>
> Inside that group, among other widgets, I have an Fl_Output.
>
> On OSX, the Fl_Output widget sometimes intercepts the drop payload,
> causes the computer to beep, and sometimes prevents the payload from
> being delivered to the group. Other times, it passes on through fine.

That sounds like a bug in the OS X implementation.

> On other platforms, it doesn't seem to do this.

Thanks for this additional verification. The behavior should always be
as close as possible on all platforms, except if the platform "dictates"
another behavior.

Let's wait a while and see if Manolo has an idea/solution for this. If
not, you should file a bug report, preferable with a working small test
program so that we can see and fix the wrong behavior. If you can
provide such a demo program, please feel free to post it here as an
attachment. Don't forget to describe the test scenario to use to see the
bug and, if necessary, the expected (desired) behavior.

> Similarly, in another portion of my program, I have an Fl_Input that
> similarly intercepts the dropped payload. On OSX, it always prevents
> the payload from being delivered. On Windows, the payload string
> briefly appears in the Fl_Input box until my program refreshes it.

Hmm, I don't understand "until my program refreshes it". What does your
program do to refresh it?

> The payload is then successfully delivered.

That's good. Anyway, a short, complete, compileable test/demo program
would be interesting to see as well.

> Is there a way to disable Fl_Input and Fl_Output receipt of dropped
> payloads without deriving a new class?

I'm not aware of one.

> Or, if that is the best way, what do you suggest?

Are you asking what to do to prevent DND in a derived class? If yes,
take a look at the FL_DND_* events and their descriptions.
http://www.fltk.org/doc-1.3/events.html#events_dnd

(FL_DND_ENTER:)
"A widget that is interested in receiving drag'n'drop data must return 1
to receive FL_DND_DRAG, FL_DND_LEAVE and FL_DND_RELEASE events."

So if you explicitly return 0 on FL_DND_ENTER events this should suffice.

BTW: There's an interesting sentence in the description: "FL_DND_*
events cannot be used in widgets derived from Fl_Group or Fl_Window."

I'm not sure what this actually means, i.e. if this is true for all
platforms, or if it is no longer true in current FLTK. I have no idea
what the reason for this sentence is (was). You seem to do just that in
your application, so I can't say if this is a "supported usage".

MacArthur, Ian (Finmeccanica, UK)

unread,
May 2, 2016, 6:02:36 AM5/2/16
to fltkg...@googlegroups.com
> I have derived a class from Fl_Group that can receive drag-n-drop
> payloads.

> Inside that group, among other widgets, I have an Fl_Output.

> On OSX, the Fl_Output widget sometimes intercepts the drop payload,
> causes the computer to beep, and sometimes prevents the payload from
> being delivered to the group. Other times, it passes on through fine.

> On other platforms, it doesn't seem to do this.

> Similarly, in another portion of my program, I have an Fl_Input that
> similarly intercepts the dropped payload. On OSX, it always prevents
> the payload from being delivered. On Windows, the payload string
> briefly appears in the Fl_Input box until my program refreshes it. The
> payload is then successfully delivered.

> Is there a way to disable Fl_Input and Fl_Output receipt of dropped
> payloads without deriving a new class? Or, if that is the best way,
> what do you suggest?


Hmm, that sounds odd.

I'm not entirely clear on how you are using the Fl_Input in this case. Can you create a minimal, compileable, example that shows what you are doing, so we can see how this effect manifests, please?

Cheers,
--
Ian



Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

Manolo

unread,
May 2, 2016, 7:31:36 AM5/2/16
to fltk.general
With this information, it is unclear why you want an Fl_Group to receive D&D events.
As Albrecht already mentionned, the FLTK doc states that such widgets cannot
receive these events:
http://www.fltk.org/doc-1.3/events.html#events_dnd

Did you try defining an Fl_Widget-derived custom object the size/location of your Fl_Group
and having its handle() member function process FL_DND_XXX events ?

Rob McDonald

unread,
May 2, 2016, 10:53:54 AM5/2/16
to fltk.general, Albrech...@online.de
On Monday, May 2, 2016 at 2:53:45 AM UTC-7, Albrecht Schlosser wrote:

That's good. Anyway, a short, complete, compileable test/demo program
would be interesting to see as well.

I'll see what I can find.

So if you explicitly return 0 on FL_DND_ENTER events this should suffice.

Ok, that is what I figured.
 
BTW: There's an interesting sentence in the description: "FL_DND_*
events cannot be used in widgets derived from Fl_Group or Fl_Window."

Too bad I didn't read that before I did it.  Other than this (work-aroundable) issue, it has been working fine.
 
I'm not sure what this actually means, i.e. if this is true for all
platforms, or if it is no longer true in current FLTK. I have no idea
what the reason for this sentence is (was). You seem to do just that in
your application, so I can't say if this is a "supported usage".

Ok, thanks for that.  I'm not sure what it means either.

Rob

Rob McDonald

unread,
May 2, 2016, 11:00:33 AM5/2/16
to fltk.general
On Monday, May 2, 2016 at 4:31:36 AM UTC-7, Manolo wrote:
With this information, it is unclear why you want an Fl_Group to receive D&D events.
As Albrecht already mentionned, the FLTK doc states that such widgets cannot
receive these events:
http://www.fltk.org/doc-1.3/events.html#events_dnd

Do you know why it says that?  Do you know if it is still true?

When I started adding drag-n-drop to my program, I had to subclass all kinds of widgets and make many changes all over the place.  It was quite a hassle.

Then, I subclassed Fl_Group and instead of having to subclass lots of widgets, I only needed one.  Better yet, I could make any widget droppable by simply placing it in a droppable group.  I could also make the drop target in my program substantially larger by making it a group that covered an entire region.  This made the drop behavior of my program easier for users to understand and use.

Frankly, a droppable Fl_Group is a great thing.  If we could understand the prohibition, it would be great to work to remove it.

Did you try defining an Fl_Widget-derived custom object the size/location of your Fl_Group
and having its handle() member function process FL_DND_XXX events ?

 No, I haven't tried anything like that yet.

Rob

Manolo

unread,
May 2, 2016, 11:57:20 AM5/2/16
to fltk.general


On Monday, 2 May 2016 17:00:33 UTC+2, Rob McDonald wrote:
On Monday, May 2, 2016 at 4:31:36 AM UTC-7, Manolo wrote:
With this information, it is unclear why you want an Fl_Group to receive D&D events.
As Albrecht already mentionned, the FLTK doc states that such widgets cannot
receive these events:
http://www.fltk.org/doc-1.3/events.html#events_dnd

Do you know why it says that?  Do you know if it is still true?
I don't know why. Your experiment suggests it's not entirely arbitrary.
 

When I started adding drag-n-drop to my program, I had to subclass all kinds of widgets and make many changes all over the place.  It was quite a hassle.

Then, I subclassed Fl_Group and instead of having to subclass lots of widgets, I only needed one.  Better yet, I could make any widget droppable by simply placing it in a droppable group.  I could also make the drop target in my program substantially larger by making it a group that covered an entire region.  This made the drop behavior of my program easier for users to understand and use.

Frankly, a droppable Fl_Group is a great thing.  If we could understand the prohibition, it would be great to work to remove it.

Did you try defining an Fl_Widget-derived custom object the size/location of your Fl_Group
and having its handle() member function process FL_DND_XXX events ?

 No, I haven't tried anything like that yet.
Could you try that, on one of your droppable-Fl_Group s?
It's very simple to implement, and could be the solution.
 

Rob

Albrecht Schlosser

unread,
May 3, 2016, 5:56:53 AM5/3/16
to fltkg...@googlegroups.com
On 02.05.2016 17:57 Manolo wrote:

> On Monday, 2 May 2016 17:00:33 UTC+2, Rob McDonald wrote:
>
> On Monday, May 2, 2016 at 4:31:36 AM UTC-7, Manolo wrote:
>
> With this information, it is unclear why you want an Fl_Group to
> receive D&D events.
> As Albrecht already mentionned, the FLTK doc states that such
> widgets cannot
> receive these events:
> http://www.fltk.org/doc-1.3/events.html#events_dnd
> <http://www.fltk.org/doc-1.3/events.html#events_dnd>
>
>
> Do you know why it says that? Do you know if it is still true?
>
> I don't know why. Your experiment suggests it's not entirely arbitrary.

Maybe we should try to check and fix this, at least in FLTK 1.4. Manolo,
can you check why the described odd behavior under OS X exists? Without
checking lots of STR's and git/svn blame it's hard to say why this
restriction is mentioned in the docs, but I'm curious, and I'll give it
a try.

> Frankly, a droppable Fl_Group is a great thing. If we could
> understand the prohibition, it would be great to work to remove it.

Yep, agreed.

> Did you try defining an Fl_Widget-derived custom object the
> size/location of your Fl_Group
> and having its handle() member function process FL_DND_XXX events ?
>
>
> No, I haven't tried anything like that yet.
>
> Could you try that, on one of your droppable-Fl_Group s?
> It's very simple to implement, and could be the solution.

IIRC I've read that suggestion previously, but this has another
drawback: you have to overlay more than one widget in the same place.
Although this is possible, it's also discouraged somewhere in the docs
(I don't know where, though).

Manolo

unread,
May 3, 2016, 1:50:35 PM5/3/16
to fltk.general, Albrech...@online.de
The Fl_Group widget has its own processing of FL_DND_XXX events
(see Fl_Group::handle(int event) and static int send(Fl_Widget* o, int event)
in src/Fl_Group.cxx).
Thus, if the user derives Fl_Group and does his/her own processing of these events
there's a high change to screw up the correct, and delicate, event processing
performed by Fl_Group.
That's why, I believe, the FLTK doc recommends not to do that.
And why the OP sees unwanted effects.

In contrast, the attached example (minor modification of test/input.cxx) shows
how to create a droppable group, by deriving Fl_Widget and putting that 'in the
background' of a unmodified Fl_Group widget.

I don't expect problems due to superposed widgets in that situation.

It's also possible to create a droppable_group class that creates an Fl_Group
and adds to it a droppable Fl_Widget the size of the group in one go.
input.cxx

Rob McDonald

unread,
May 3, 2016, 5:11:01 PM5/3/16
to fltk.general, Albrech...@online.de
Manolo,

This whole discussion has helped me come to a better understanding of what is going on -- and through that, I think I've come to a workable solution.

Your dropable group might work, but I wonder what would happen if a Fl_Input was placed in that group -- if the user dropped on top of the Fl_Input, would it grab the payload, or would it be sent on down to the invisible Fl_Widget underneath?

To me, the outright prohibition of "don't do this" is probably overly severe -- there are lots of things in code and in FLTK where you have to use care.  There is a big difference between 'don't' and 'be careful'...

So, lets look at some code...

Before this discussion, my derived droppable group's handle() looked like this.

int My_Group::handle(int event)
{
    int ret = Fl_Group::handle(event);

    if( m_AllowDrop )
    {
        switch ( event )
        {
        case FL_DND_ENTER:
        case FL_DND_DRAG:
        case FL_DND_RELEASE:
            ret = 1;
            break;
        case FL_PASTE:
            if( callback() )
            {
                do_callback();
            }
            ret = 1;
            break;
        }
    }
    return ret;
}

You can see that I explicitly chose to first call Fl_Group::handle() and then continue processing after it was complete.

I have come to realize that Fl_Group plays a role in passing drag-n-drop events down through the hierarchy -- and handle() was doing more than returning 0 or 1, it was actually taking action (things I thought would happen in a callback someplace).

I have since changed my group's hande() to this:

int My_Group::handle(int event)
{
    if( m_AllowDrop )
    {
        switch ( event )
        {
        case FL_DND_ENTER:
        case FL_DND_DRAG:
        case FL_DND_RELEASE:
            return 1;
            break;
        case FL_PASTE:
            if( callback() )
            {
                do_callback();
            }
            return 1;
            break;
        }
    }

    return Fl_Group::handle(event);
}

The last thing I do is call Fl_Group::handle().  If it encounters a drag-n-drop event, it is handled entirely here, never getting passed to the underlying Fl_Group.

In my case, this has the 'advantage' that it blocks all children from receiving the drag-n-drop events.

The thing that really sent me down the wrong conceptual path was that I didn't expect Fl_Input and Fl_Output to handle drag-n-drop events 'out of the box'.  Everything else in FLTK needs to be 'manually wired' to handle DND, so I expected that to carry through the rest of the library.

Rob

Albrecht Schlosser

unread,
May 3, 2016, 6:04:22 PM5/3/16
to fltkg...@googlegroups.com
On 03.05.2016 23:11 Rob McDonald wrote:
> Manolo,
>
> This whole discussion has helped me come to a better understanding of
> what is going on -- and through that, I think I've come to a workable
> solution.
>
> Your dropable group might work, but I wonder what would happen if a
> Fl_Input was placed in that group -- if the user dropped on top of the
> Fl_Input, would it grab the payload, or would it be sent on down to the
> invisible Fl_Widget underneath?

AFAICT Fl_Group handles events in the opposite order of children in the
group, i.e. last child is checked first. This assures some kind of
"layers" of widgets. Drawing is done top-down so the last widget is on
top of all other widgets, but events are distributed to children
bottom-up so that the last (top-most) child gets the event first.

Hence, to answer your question, it depends ... If the droppable widget
was the last widget in the group it would get the first choice to take
the DND event, but if it was the first child then all other widgets
would be checked (boundary check, see event_inside()) before the
droppable widget. You can imagine this as some kind of a layer concept
so that the last (later) widget in a group is always on top of all other
widgets. This is the "normal" event delivery model.

If your droppable group intercepts this, because your handle() method
does it differently (prohibiting delivery to children), then that's your
choice.

> To me, the outright prohibition of "don't do this" is probably overly
> severe -- there are lots of things in code and in FLTK where you have to
> use care. There is a big difference between 'don't' and 'be careful'...

The docs say something different. They say "you cannot"! I doubt that
this is true in the sense of the words. It should probably read "you
should not" (i.e. don't do this, as you wrote).

> So, lets look at some code...

[code elided]

> The last thing I do is call Fl_Group::handle(). If it encounters a
> drag-n-drop event, it is handled entirely here, never getting passed to
> the underlying Fl_Group.

Okay.

> In my case, this has the 'advantage' that it blocks all children from
> receiving the drag-n-drop events.

Looks plausible.

> The thing that really sent me down the wrong conceptual path was that I
> didn't expect Fl_Input and Fl_Output to handle drag-n-drop events 'out
> of the box'. Everything else in FLTK needs to be 'manually wired' to
> handle DND, so I expected that to carry through the rest of the library.

I'm afraid I can't follow you here. Fl_Input needs to do drag'n'drop
handling because text could be d'n'd'ed inside or into an Fl_Input
widget. Nothing needs to be 'manually wired' here. Sorry, I really don't
get what you want to say in the above paragraph.

Rob McDonald

unread,
May 3, 2016, 7:55:42 PM5/3/16
to fltk.general, Albrech...@online.de
On Tuesday, May 3, 2016 at 3:04:22 PM UTC-7, Albrecht Schlosser wrote:
> The thing that really sent me down the wrong conceptual path was that I
> didn't expect Fl_Input and Fl_Output to handle drag-n-drop events 'out
> of the box'.  Everything else in FLTK needs to be 'manually wired' to
> handle DND, so I expected that to carry through the rest of the library.

I'm afraid I can't follow you here. Fl_Input needs to do drag'n'drop
handling because text could be d'n'd'ed inside or into an Fl_Input
widget. Nothing needs to be 'manually wired' here. Sorry, I really don't
get what you want to say in the above paragraph.

I agree, Fl_Input is already 100% ready for DND handling.

I did not expect that.  When I first encountered FLTK DND, I was implementing a strange case.  I needed to drag from a Fl_Button and drop on arbitrary other widgets.  And, I was passing a payload that should never be user-visible.

I never experienced/used the 'traditional' DND handling that Fl_Input is set up for.

So, when I read the DND documentation and implemented things, I got a very do-it-yourself feel.  I made the mistake of applying that perspective across the board.  I did not expect that Fl_Input/Fl_Output would support DND 'out of the box'.  Consequently, when Fl_Output was trapping my events and sounding the alarm bell, I could never figure out what was going on.

Thanks for all the help,

Rob



Manolo

unread,
May 4, 2016, 1:09:30 AM5/4/16
to fltk.general, Albrech...@online.de

On Tuesday, 3 May 2016 23:11:01 UTC+2, Rob McDonald wrote:
Manolo,

This whole discussion has helped me come to a better understanding of what is going on -- and through that, I think I've come to a workable solution.

Your dropable group might work, but I wonder what would happen if a Fl_Input was placed in that group -- if the user dropped on top of the Fl_Input, would it grab the payload, or would it be sent on down to the invisible Fl_Widget underneath?

Get the answer by running the modified input.cxx program.
Reply all
Reply to author
Forward
0 new messages