Page 1 of 1

[BUG] Event stops firing after returning FALSE

Posted: Tue Nov 03, 2009 06:58
by Van
CEGUI 0.7.1 SVN Branch

I'm pretty sure this one is a bug. I'm having trouble tracking it down.

When an event call back, such as CEGUI::Editbox::CharacterKey returns FALSE, the event will not fire again unless the element has another event fire first. This is most evident with the CEGUI::Spinner. We have subscribed to the CEGUI::Spinner::CharacterKey event. When a key is pressed the event fires but if we don't handle it and return false the event will not fire again unless I click one of the spinner arrows (up or down) to change the value. The same happens with the MouseWheel and MouseDoubleClick events too.

Re: [BUG] Event stops firing after returning FALSE

Posted: Thu Dec 03, 2009 09:53
by CrazyEddie
Thanks for the report. I'll test it out :)


Re: [BUG] Event stops firing after returning FALSE

Posted: Sat Dec 05, 2009 13:36
by CrazyEddie
I think the issue here is one relating to where the subscribers are attached. Basically, the Spinner is a DefaultWindow with an Editbox and two PushButton widgets attached as children. This means that when subscribing handlers to the Spinner itself (i.e. the parent window), events may not be received. The resulting behaviour may be different now to earlier versions due to the fact that input events are now - in general - not passed back up the window hierarchy, whereas previously they were. An exception to this general behaviour exists with keyboard events, though the backwards propagation will always terminate upon reaching an editbox or editbox-like widget.

Note that while the above described behaviour is now how things are designed and are as intended, some of the resulting behaviour for these compound widgets, is perhaps not ideal (at least given how things behaved previously, which in some cases might have appeared 'better' than what we have right now).

The solution at the moment is to obtain a pointer to the 'real' widget or widgets that you're interested in and subscribe the events there (perhaps in addition to the parent container also).


Re: [BUG] Event stops firing after returning FALSE

Posted: Mon Dec 07, 2009 20:57
by Jamarr
input events are now - in general - not passed back up the window hierarchy...the above described behaviour is now how things are designed and are as intended

I haven't played with v0.7 much, so I'm not sure how far this issue reaches. And I don't mean to derail the thread, but I wanted to comment on the above information.

This is one of the same aspects of wxWidgets that I /really/ hated. In wxWidgets, only keyboard and a handful of other (command) events are propagated (and even then, only to a certain extent). Since I was building new widgets composed of exisitng widets, I needed mouse and other events to automatically propagate up the parent chain so that unrelated classes would not need to know the inner workings/composition of the parent widget.

In order to accomplish this, I basically had to write a custom event-propagator class that would translate events as if they where fired from the parent (eg, mouse-events needed their coordinates updated to be relative to the parent, etc.) and then pass the event onto the parent's subscribers. I never understood why wxWidgets does this. And I've been unable to conceive any logical reasoning for this behavior. It sounds like CEGUI is trotting down the same road.

If the mouse-moves in a child-window, is it not logical to think of the mouse-moving in relation to the parent? If the keyboard is pressed in an editbox, why is it illogical to think of the keyboard being pressed in relation to the parent? I do not think that the child (or whatever mechanism is preventing propogation) should decide who does and does not need to handle the event; subscribers should determine weather or not they want to handle it. To me it seems illogical to deny propagation for any reason.

Perhaps I misunderstood and/or am too ignorante of the circumstances; either way I would like to be enlightened.

Re: [BUG] Event stops firing after returning FALSE

Posted: Tue Dec 08, 2009 14:26
by CrazyEddie

I think it's a situation where it's very hard to please everybody, and I'm actually finding it hard to justify taking one stance or another, or indeed coming up with any reason for making the change other than the fact I came to hate the way it was...

In the original CEGUI library, there was no propagation of events at all. The situation in Mk-2 prior to 0.7.0 was that input events were always propagated, this had potential to cause issues because if user clicks on window 'B' that's a child of window 'A' - unless there's a handler of some kind on 'B' to mark the event handled, the event always propagates to 'A' which may handle the event itself, the issue is that it can produce undesired results because the user did not really click on 'A'; they clicked 'B'. I could not (and still can't) recall why I put that event propagation into the system for Mk-2, every time I thought about it, it made no sense to me.

Add to this situation the problem where we needed to return a 'correct' value from the inject functions - the fix for which basically was to mark all mouse events handled except in one special circumstance, so now propagation would cease anyway, since all regular windows always mark the input event as handled.

Finally, before deciding to take it out, I had an - admittedly very quick - look at some of the UI systems out there (IIRC it was Qt, Wx and native Win32), and could not see a similar behaviour, and so the decision was made (for better or worse!).

Now, I'm not dead set against having it back in the system providing three conditions are met... 1) There has to be a compelling argument for having it in. 2) The current top-level inject behaviour should be maintained[1], and 3) Someone else has to do the work ;)


[1] Input injection is going to be reviewed shortly and perhaps replaced with something else, so this may not actually be important, depending on the outcome of that.