[GUI] Another call for votes

Wolfgang Thaller wolfgang.thaller@gmx.net
Tue, 18 Mar 2003 17:57:54 +0100

On Dienstag, M=E4r 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=20=

>> unregister the callback.
> I disagree with this design. It is very awkward to install callbacks=20=

> this way as we
> have to maintain the "unregister" function. We can no longer use=20
> "nice" syntax like:
>  button [on click :=3D messageBox "hi there"]

Yes, that looks nicer, but it now we can have only one callback for one=20=

event; I believe the people who first brought this design up (I was=20
only copying what I had read on this list) were thinking of allowing=20
multiple callbacks to be installed for a single event, as can be done=20
using GTK's signal/slot mechanism.

So what about...

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

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,=20=

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=20=

the nice syntax or the nice functionality, so I withdraw my vote on 2)=20=

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=20
Changes?" dialog, I'd perhaps add a callback for the "window about to=20
close" event. No problems here.
Suppose that we also have a utility window that shows information about=20=

some item in the document. When the document window closes, the utility=20=

window closes, too (we'd like to have a second "close" callback on the=20=

document window), but the utility window can also be closed by the user=20=

before the document closes (we'd like to uninstall our "close" callback=20=

in that case).

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

> This mechanism is enough to build a nice framework around. For=20
> example, you
> could add a callback to the existing ones.
>  buttonAddOnClick io button
>    =3D 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=20=

might want to use a threadsafe buttonModifyOnClick :: Button -> (IO ()=20=

-> IO ()) -> IO () instead.

> The only think lacking is indeed the "unregister" call but I think it=20=

> is a highly
> unusual thing to deinstall a callback without replacement on an=20
> 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=20=

said that mouse moved events are really bad for remote connections, and=20=

I wouldn't bet it's so unusual to track mouse movements only for a=20
short period of time and then uninstall the callback.