[Gd-hackers] gtk interface: shorten identifiers, ... ?

Danny Milosavljevic danny_milo at yahoo.com
Mon Nov 27 19:49:19 CET 2006


Hi,

On Mon, 27 Nov 2006 02:26:17 +0100, Andreas Bogk wrote:

> Danny Milosavljevic schrieb:
>> I wonder how to modify the gtk interface in
>> to make an example like this possible:
> [snip]
>> That is,
>> 1) use short identifiers for "object methods"
> 
> I don't think that's a good idea. The GTK API is specified in terms of
> the identifiers with prefix, and somehow munging that seems odd.  

Well, I know of no other gtk binding that keeps the prefixes (not the
python bindings and not the dotnet bindings; I didn't check the java
bindings yet).

> You
> will probably also run into trouble deciding which prefix to drop when,
> as GTK doesn't really have object methods.  

It does have, mostly. If first parameter is a g object, then it is an
object method, with a few exceptions (very very few for anything other
than in glib).

(I don't care much for exporting glib abstractions (except gobject) and
mostly need only gtk/gdk to integrate into UNIX GUI, not to use ghashtable
or something :))

Note that at

http://svn.berlios.de/svnroot/repos/gtk2q/

I already created a gtk binding (and xfce, gstreamer, diacanvas,
exo) (for freepascal), complete up to gtk 2.6 support. 
So I have a vague idea what it is like. :)

> Also, the author constantly
> has to look up whether a specific prefix is dropped or not (and dropping
> all of them will probably make a mess).

Dropping all prefixes from methods of objects that are-a g object works
nicely, and the others are mostly C support functions which are not
required in gtk bindings for dylan (because the language
already has their native version, usually) - and keeping the prefix on
those C support functions is a healthy deterrent from using them.

> 
> Adding a name mapper to melange might do it, but you might have to touch
>  parts of the GTK support code.

I'll try. I'm not particularily versed in melange, so I'll be sure to
bother the list with questions :)

>> 2) use symbols for flags
> 
> That one should be doable using a mapping, as you guessed.  Use the map:
> and equate: arguments in the melange definition, and play around with
> export-value and import-value.  Grepping for those functions in the
> repository should find you examples.

Okay, I'll see about that after I got the method names down to simple verbs. 

How do people manage to cope with verbs that long? Bigger screen/brain
than me? ;) 
I mean I don't need abbreviations like "sw" for "show" (UNIX
*cough cough*), but to call "gtk-widget-show" with/on a <window>, come on.

Of course all this is only doable if dylan supports folding the 
functions that arise from that into a generic function. e. g. "clear"
would have:

clear(<cell-layout>) => ()
clear(<cell-view>) => ()
clear(<clipboard>) => ()
clear(<combo-box-entry>) => ()
clear(<combo-box>) => ()
clear(<entry-completion>) => ()
clear(<icon-view>) => ()
clear(<list-store>) => ()
clear(<tree-store>) => ()
clear(<tree-view-column>) => ()

Or for a more evil example, "copy-clipboard" would have:

copy-clipboard(<text-buffer>, clipboard :: <clipboard>) => ()
copy-clipboard(<editable>) => ()
copy-clipboard(<entry>) => ()
copy-clipboard(<spin-button>) => ()

>> 3) add actual slots for signals (so that it isn't so easy to specify
>> non-existant signals)
> 
> I don't think that's a good idea either, there might be signals added
> dynamically.  

I didn't say it had to be exclusive :) you can have both.

Also, g signals are actually not just g-signal-connect, but rather:

<g-signal>:
  (id :: <integer> not really useful)
  name :: <symbol>
  methods :: <set>
  connect(<function>)
  disconnect(<function>)
  emit()
  freeze()
  thaw()
  block()
  unblock()
  stop-emission()
  
<widget>:
  destroy :: <g-signal>
  ...

To use object-oriented-speak. :)
That said, I'm not sure object-oriented is best there.
It might also be nice to fold it into the original object, like:

<g-signal> = <symbol>

<window>:
  connect(<g-signal> == #"destroy", <function>)
  disconnect(<g-signal> == #"destroy", <function>)

(I didn't do that in the gtk2q pascal bindings because the compiler
literally took hours to compile it, then :->)

> But if you want it, play around with gobject2-tool, and
> try to get your fingers at a list of signals for a class, and then emit
> functions for each.

I'll try.

> In fact, enough of glib is probably wrapped, so you can write the
> generator in Dylan.
> 
> Note that semantically there is no difference between a slot access and
> a function call.  You can just emit code like this:
> 
> define method response (dialog :: <gtk-dialog>)
>   make(<signal-reference>, object: dialog, name: "response")
> end;
[...]
> The syntax would be slightly different, though:
> 
>   connect(dialog.response, method() ...

That's nice, actually.

> 
> An expression like:
> 
>  dialog.connect.response(method() ...
> 
> would try to access a slot response on the object returned by connect,
> and call the value of that slot as a function, passing in the method.
> 
> But still, this construction generates overhead for almost no value.

Overhead? Like where? Connecting signals isn't in the critical path, anyway ;)

I wonder why they were made strings in the first place (in the gtk/C
interface), as opposed to published constants. (ok, so there is _one_
special case "notify::<property>")

(yes, I am heavily biased to static languages that find most of those
kind of errors at compile time - given they are not passed as strings...).

It's not like new signals are created on a class dynamically while the
program is executing, either. At least not in all of gtk and Xfce (of what
I can remember... yeah yeah).

> 
>> 4) add support for "make(<window>" etc
> 
> The g_object_new call is what you need to look at to implement this.

Okay, I will try.

Thank you :)

cheers,
  Danny




More information about the hackers mailing list