GNOME Bugzilla – Bug 542337
Allow anjuta to handle clicks on widgets in designer
Last modified: 2009-01-20 22:25:21 UTC
I'm proposing to send all signals to glade project and anjuta will be connected to it. Using an integer instead of a boolean allows to control calling of default handler.
Created attachment 114297 [details] [review] The patch makes it possible to intercept the widget signals
Ok this is complex so lets shed some light: - Events are caught from the actual widgets by GladeWidget implementation - For filtering/marshalling reasons, all events are sent to the parenting GladeDesignLayout - The layout in turn decides which GladeWidget to send the event for processing. We need per widget processing for GladeFixed implementations (Drag/Resize in various container types), gladefixed uses the gladewidget::button-events. Now, furthermore, there is a serious of priorities to respect with button events - first button click on a widget is used to select the widget - you are not allowed to catch that and return TRUE. The second event is used either, in the case of GladeFixed and modifiers active, may be used for a drag/resize - asides from that the widget is left to process the event in the glade environment and look cute that way. So, We can add an event notification on the project sure - but first, what are you using them for ? shall it be a second stage emission that we can send out directly from the GladeDisignLayout event hub ?
Created attachment 117090 [details] [review] Patch A new signal in design layout for listening and intercepting widget events. I really cannot figure out how I managed to miss that in spite of a lot of time spent working on events and especially clicks. Probably, it's because the lines "if (!layout) return glade_widget_event (gwidget, event);" (which send the event directly to the widget if there's no design layout). Thanks for the explanation.
Ok thaks, few nitpicks and comments: - you have a stale diff included from glade-project.h - please include C context in your patches (i.e. the -p option to diff) (otherwise I have to open sources to find what functions your diffs apply to... reading those line number... gah) - AFAICS your signal return value is used to either stop the emission or not, is there any reason not to use a normal boolean handled accumulator ? Now this one is the important one, I want it done a little backwards from the way you did it, you registered the signal as RUN_LAST, and handle glade widgets in the layout's class handler, *after* third party callbacks are honored. What we need here is to: a.) Run the glade widget handlers and mind the return value b.) if the return value of the glade handlers is still "unhandled", then fire a signal for third party handlers (at this point it probably doesnt matter to us about the return value of the signal, although a boolean accumulator could help just for convenience for third party signal callbacks). Note we wont be able to accomplish this by changing the signal to RUN_FIRST, because from the RUN_FIRST class handler we have no way I can see to abort the signal emission (I may be wrong here, but Im quite sure that requesting an abort from the class handler doesnt cancel out the next stage of signal emission).
(In reply to comment #4) [...] > What we need here is to: > a.) Run the glade widget handlers and mind the return value > b.) if the return value of the glade handlers is still "unhandled", > then fire a signal for third party handlers (at this point > it probably doesnt matter to us about the return value of the > signal, although a boolean accumulator could help just for > convenience for third party signal callbacks). > Ok I noticed I have something else to clarify... basically, here is the "deal" we are willing to make. a.) If you want to get absolutely all events from glade, then you are not allowed to abort the native glade signal callbacks. b.) If you want to some kind of interactive actions with mouse clicks, specifically any actions that modify the GladeProject, you'll want/have to abort glade callbacks, in which case you must wait in line and see if that signal ever comes. Now, if what you want is "a", then were in bussiness, if you want "b", then it gets a little more complex, because in the case of "b", you'll want to fire the third party callback: AFTER the glade bussiness logic handlers have been called and BEFORE by default throwing the event at the actual widget so that the button "clicks" in the UI. I.E., you are allowed to abort callbacks before they are handled by the actual widget in the UI, but not before they are handled by glade.
Using my patch I can catch an event before and after glade handler, so I get full control of widget events. Using my accumulator function the signal emission may be aborted by class handler or any other handler and the last return value will be used. The first bit of handler return value means "abort" and the second bit contains a boolean value. In this way I will abort events selectively, so I cannot see any problems.
Yes but there are two problems I previously outlined: a.) The order in which callbacks are called when they trigger commands that effect the project is important, its important for instance, that glade sets selection on the first click, then project actions, and in the last case the widget natural actions. b.) Your patch allows third parties to handle the event before glade *and* abort the emission - I already stated this is not part of the deal.
First of all, I wanted to handle double clicks in anjuta plugin. The problem is how to block the second click of double click, because double click signal is received after all single clicks. Secondly, I planed to make something like a travesty of preview mode, in which all clicks would be send directly to widgets. Probably, that's rubbish, though I cannot see any problems in making the possibility of changing the glade behavior. So, will the changing of behavior cause any serious problems? Also, GtkFixed seems to be little buggy and AFAIK there was no changes to that problems. I'll create a separate bug for one of the bugs. The second bug is that GtkMixed handles clicks on a wrong stage of their processing. I think I will have more details tomorrow.
Please let me know about the problems you find with GtkFixed/GtkLayout manipulations... Thanks for giving me more insight on what you want to do, I had not considered what happens with double clicks either, the code in this patch is clean, thats not a problem, although I wonder if theres a way to simplify the handler to have a simple boolean return value. I'm going to look through it more in depth this week, we have a very long track record of bugs regarding event handling, and its been working well for quite some time, after several refactorings.
I looked at it again, I wonder what is the behavior of the callback when connecting with g_signal_connect_after() ? I think the "after" signals run in a different emission stage which could be a problem. I would prefer if connect_after() meant that you will be called only if glade_widget_event() returned FALSE for that event (i.e. allowing the user to serialize his callback after glade initial selection click/drag resize mode - but still before native widget event handlers) - if connect_after doesnt behave this way, then we wont be able to add callbacks to events in what I believe to be the most sensible place: after selections and before native event handlers. Also, if we have the ability to connect before or after the GladeWidget handlers, is there a reason for the integer return value ? the value returned still symbolizes whether the event is propagated further. Is there any reason you would want to abort the glade handler manually and still let the native widget handler run ? (i.e. return abort|false) I would prefer to see the widget come before the event, ideally: gboolean widget_event (GladeDesignLayout *, GladeWidget *, GdkEvent *); The added GladeDesignLayout::widget-event should come with a gtk-doc statement, and an explanation about the effects of connecting before and after the signal. NOTE: if we cant serialize all the callbacks into one signal, we can consider adding 2 (boolean handled) signals to be run at different stages.
By connecting after default handler it behaves just as you wish - the first is glade logic, the second is custom handler and the third is widget handler, propagation can be aborted at any stage using boolean handled accumulator. But what I need is: - to block all clicks from getting to widgets, because I want to use double click, but GDK_BUTTON_PRESS event is emitted before GDK_2BUTTON_PRESS, so I have no idea how to block it without the total blocking; - in a special mode, all click are delivered directly to widgets, so you can perform any necessary actions on them. This is the only place where abort|false is needed. I suppose the special mode to be turned on by holding some key or something else. Why should a widget come before an event in the parameter list? I'm not sure that splitting of event handling into 2 signals would be a good idea. I hope some documentation will help to make things cleaner for everybody. PS: I cannot reproduce that bugs anymore, so they seem to be fixed.
(In reply to comment #11) > By connecting after default handler it behaves just as you wish - the first is > glade logic, the second is custom handler and the third is widget handler, > propagation can be aborted at any stage using boolean handled accumulator. But > what I need is: > - to block all clicks from getting to widgets, because I want to use double > click, but GDK_BUTTON_PRESS event is emitted before GDK_2BUTTON_PRESS, so I > have no idea how to block it without the total blocking; > - in a special mode, all click are delivered directly to widgets, so you can > perform any necessary actions on them. This is the only place where abort|false > is needed. > I suppose the special mode to be turned on by holding some key or something > else. Fair, so long as they are both possible, particularly that a connect_after() callback is not fired when a widget is initially clicked for selection - then we have all the possibilities. > > Why should a widget come before an event in the parameter list? Just because is does in glade_widget_event(), and it also does in gtk_widget_event()... and also in all the event signals of a widget, basically for no technical reason, except to not have to consult the docs/headers when typing code ;-) > > I'm not sure that splitting of event handling into 2 signals would be a good > idea. I hope some documentation will help to make things cleaner for everybody. No no, so long as both emission stages can be treated with the same signal, theres no need for another one.
Created attachment 126803 [details] [review] Widget events v3 I added some docs for the signal and changed order of its parameters.
Patch commited in trunk