Re: Another call for votes

Wolfgang Thaller <[email protected]>
Newsgroups gmane.comp.lang.haskell.gui
Message-ID <[email protected]>
On Dienstag, Mär 18, 2003, at 12:33 Europe/Vienna, Daan Leijen wrote:

> Hi all,
>
>> 2) For every callback, there should be a register function.
>> The register function should return an IO action that can be used to 
>> unregister the callback.
>
> I disagree with this design. It is very awkward to install callbacks 
> this way as we
> have to maintain the "unregister" function. We can no longer use 
> "nice" syntax like:
>
>  button [on click := messageBox "hi there"]

Yes, that looks nicer, but it now we can have only one callback for one 
event; I believe the people who first brought this design up (I was 
only copying what I had read on this list) were thinking of allowing 
multiple callbacks to be installed for a single event, as can be done 
using GTK's signal/slot mechanism.

So what about...

2) Installing Callbacks
     2a)
         For every callback, there should be a register function.
         The register function should return an IO action that can be 
used to unregister the callback.
         There can be multiple callbacks for one event.
     2b)
         Callbacks are set using a general attribute get/set mechanism 
that we will probably design soon.
         There can be only one callback for one event.

Please note that it is very easy to emulate one option using the other, 
so the features of the backend libraries are probably not an issue here.

2a can, of course, be useful in many situations. I'm not sure if I want 
the nice syntax or the nice functionality, so I withdraw my vote on 2) 
and abstain for now. Everyone please keep discussing :-)


I'd like to provide an example of where I'd prefer to have 2a:

Suppose we have a document window. In order to support a "Save 
Changes?" dialog, I'd perhaps add a callback for the "window about to 
close" event. No problems here.
Suppose that we also have a utility window that shows information about 
some item in the document. When the document window closes, the utility 
window closes, too (we'd like to have a second "close" callback on the 
document window), but the utility window can also be closed by the user 
before the document closes (we'd like to uninstall our "close" callback 
in that case).

In most other situations, I would probably prefer the single-callback 
approach because of the opportunities for nicer syntax.


> This mechanism is enough to build a nice framework around. For 
> example, you
> could add a callback to the existing ones.
>
>  buttonAddOnClick io button
>    = do prev <-buttonGetOnClick button
>         buttonSetOnClick (do{ io; prev }) button

Which is fine as long as you don't want to uninstall a callback. And we 
might want to use a threadsafe buttonModifyOnClick :: Button -> (IO () 
-> IO ()) -> IO () instead.


> The only think lacking is indeed the "unregister" call but I think it 
> is a highly
> unusual thing to deinstall a callback without replacement on an 
> existing widget.
> Normally, the callbacks are deinstalled when the widget dies.
> But for completeness, we might want to have:
>
>   buttonIgnoreOnClick :: Button -> IO ()

Definitely. For button clicks, it is a non-issue, but some X folk have 
said that mouse moved events are really bad for remote connections, and 
I wouldn't bet it's so unusual to track mouse movements only for a 
short period of time and then uninstall the callback.


Cheers,

Wolfgang
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.