www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Native GTK bindings v2

reply Artur Skawina <art.08.09 gmail.com> writes:
What's new?

 - Now, in addition to

   GLib, GModule, GObject, Gio, GdkPixbuf, Pango, PangoCairo, PangoFT, Gdk, Atk
and Gtk+

   there are also bindings for

   Clutter, ClutterX11, Cogl, CoglPango and Mx.

 - Struct inheritance. No more need for "container.add(&vbox.widget);", you can
   write that as just "container.add(vbox);", the compiler will do all the work
   to check if the 'vbox' is somehow derived from 'widget', and convert the
   pointer by itself.

   This works not only for "struct Widget {}; struct VBox { Widget widget; ...
};",
   but also for "struct Widget {}; struct VBox { Widget* widget; ... };".
   You can extend built-in widgets and still use them with the std APIs.

-  Objects can now be constructed as "gtk.VBox(0, 0)";
   the old way, ie "gtk.VBox.new_(0, 0);" still works.

-  All methods that take a (char*) pointer now also silently accept D strings;
   casting to (char*) and/or calling toStringz are no longer necessary. It will
   be done implicitly every time you try to pass a D string; you can still pass
   a (char*) to avoid the copy.

-  GTK (GObject) interfaces supported.

-  Better error messages when registering signal callbacks (the messages given
by
   the compiler when a template instantiation fails are not very helpful and, as
   it typically happens via several alias levels, were often just confusing).

-  Some 64-bit fixes (I don't have a 64-bit GTK stack ATM, so there could be
   more problems around).

-  The pre-generated D modules were built using newer library versions
   (still GTK2, only the glib version is newer than that).

-  New examples: Clutter and Mx. Trivial, but enough to get you started.


A D GTK app now looks like this:

   http://repo.or.cz/w/girtod.git/blob/refs/heads/master:/example_gtk.d

doesn't need a single cast (other than for skipping the string copies, using
(void*) library APIs and object lookup tricks, all of which could be avoided, 
but I intentionally didn't do this in the example), looks much better than
the equivalent C version would and couldn't be done any more efficiently in C
(assuming same compiler middle/backend and ignoring the string differences, as
for most cases these don't matter. The convenience makes up for the few extra
copies and these can be avoided in every case where performance really matters).


The code is here: http://repo.or.cz/w/girtod.git

The easiest way to try the bindings is probably to check out the "gtk2" branch,
copy the "gtk2" directory to your app directory and import from there.

The girtod tool used to generate the D modules lives in the "master" branch.
When used with different lib versions than the ones I tried it on, it may need
a few tweaks; sometimes new types appear or move between the libs, new weird or
broken introspection data shows up etc.

artur

PS. Are there any sane Cairo D binding out there? (What's "sane"? Well, if
    there's a "class" in there somewhere then it's not sane)
Apr 01 2012
next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 04/13/12 15:06, bioinfornatics wrote:
 Le dimanche 01 avril 2012 à 21:23 +0200, Artur Skawina a écrit :
 The code is here: http://repo.or.cz/w/girtod.git

 The easiest way to try the bindings is probably to check out the "gtk2" branch,
 copy the "gtk2" directory to your app directory and import from there.


 why use your library instead https://github.com/gtkd-developers/GtkD

You should use whatever suits your needs. My "library" is not really a library, but just a set of wrapper templates that call the real C library functions. The advantage is no overhead, the disadvantage is sometimes a bit uglier syntax (but that area improved a lot since v1). Note that there are a few things that could be done, but currently are not implemented, simply because i haven't needed the functionality so far. Things like subclassing and registering gobject classes - it all can be done manually, but could be made a lot easier with a little help from the bindings (btw, does gtkd help here?). Other than that, everything needed by a typical app (that does not need to create custom widgets or actors) should be there.
 why do not contribute to this project?

The approaches are completely different, so there's not much that could be shared. In short: if you don't mind working with a layer that makes you access small structs containing just four integers via an extra D class instance, which only contains a pointer to said struct, then gtkd might be for you. But then you may want to consider using something like Pike [1] instead of D... artur [1] http://pike.ida.liu.se/generated/manual/ref/chapter_1.html#4 http://pike.ida.liu.se/generated/manual/modref/ex/predef_3A_3A/GTK2.html
Apr 14 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
At first I confused your project with GtkD. I'll take a look at it, to see how
it compares. Many examples for Gtk use C code, and I end up looking for the
correct GtkD class that offers the function. Otherwise I quite like the
classical inheritance that is possible with GtkD, whereas you use the "alias
this" trick, which is fair enough. Also you can bind events like onExpose
naturally to class methods in GtkD. There is no data pointer involved.
On the other hand small executables are my cup of tea. I've compiled a small
Haskell Gtk application, that weighted ~10 MB (stripped) and the same program
in D using GtkD was 3.4 MB in size. Let's see...

-- 
Marco
Apr 21 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 21 Apr 2012 14:26:59 +0200
schrieb Artur Skawina <art.08.09 gmail.com>:

 On 04/21/12 12:24, Marco Leise wrote:
 At first I confused your project with GtkD. I'll take a look at it, to see how
it compares. Many examples for Gtk use C code, and I end up looking for the
correct GtkD class that offers the function. Otherwise I quite like the
classical inheritance that is possible with GtkD, whereas you use the "alias
this" trick, which is fair enough. Also you can bind events like onExpose
naturally to class methods in GtkD. There is no data pointer involved.

Hmm, some sugar is likely possible for things like signal callbacks; i'll think about it.
 On the other hand small executables are my cup of tea. I've compiled a small
Haskell Gtk application, that weighted ~10 MB (stripped) and the same program
in D using GtkD was 3.4 MB in size. Let's see...
 

"example_gtk", which is probably the smallest /useful/ GTK2 app is 315K here (32-bit x86 linux), after commenting out the _dumpObj(event) call. (I wonder how large an equivalent gtkD version would be... But, as i care more about /runtime/ efficiency, it's not a very interesting metric) If you care about executable sizes, some GDC specific notes: - compile with "-ffunction-sections -fdata-sections -Wl,--gc-sections" Things like std.bitmanip unconditionally emit functions, which will be rarely used, but bloat the executable. - do *not* compile with "-Wl,--export-dynamic" This option will slow down linking, while enabling better backtraces; unfortunately it will also prevent the gc-sections optimizations above from working. - use '-frelease -fno-bounds-check' - use '-flto' - do not use '-g' together with '-flto' for the final executable linking GCC (4.6) bug, can result in ICE. - strip the executable artur

I just noticed cairo.d is still a dummy. I am using image surfaces. "-ffunction-sections -fdata-sections -Wl,--gc-sections" is a good idea, but I found it to break exception throwing for my programs. -- Marco
Apr 21 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 21 Apr 2012 21:46:18 +0200
schrieb Artur Skawina <art.08.09 gmail.com>:

 On 04/21/12 19:16, Marco Leise wrote:
 I just noticed cairo.d is still a dummy. I am using image surfaces. 

Yes, cairo.d is generated from GI data too and only contains the few symbols and types required to use the other libs. There are other cairo D bindings, which probably could be used with a small glue layer. Making sane cairo bindings is on my to-do list, but I won't have the time for that in the next few weeks.

No hurry, I have GtkD. It's biggest win is that it is considered stable and usable by many for a long time.
 "-ffunction-sections -fdata-sections -Wl,--gc-sections" is a good idea, but I
found it to break exception throwing for my programs.
 
 GDC/DMD? Would you happen to have a small contained sample that breaks?
 Not garbage collecting sections means executables that are several times
 larger (IIRC for the small gtk example the difference was 1.2M vs 0.3M).
 
 artur

No example. I don't know what I tried it on, but I remember that I was hunting a bug that occurred, because an important exception wasn't thrown. I think it was a plain old "throw ...". It was with GDC, since DMD doesn't offer a one-section-per-function flag. I can give it a second try. I didn't post any bug reports, since gc-sections is a difficult beast: https://bitbucket.org/goshawk/gdc/issue/293/ffunction-sections-fdata-sections-for https://bugzilla.redhat.com/show_bug.cgi?id=788107 Without support from Iain, I don't expect a bug would be fixed by adding some hack to keep a function from being garbage collected (or whatever caused me problems). -- Marco
Apr 21 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Sun, 22 Apr 2012 00:54:41 +0200
schrieb Artur Skawina <art.08.09 gmail.com>:

 On 04/22/12 00:06, Marco Leise wrote:
 Am Sat, 21 Apr 2012 21:46:18 +0200
 schrieb Artur Skawina <art.08.09 gmail.com>:
 
 On 04/21/12 19:16, Marco Leise wrote:
 I just noticed cairo.d is still a dummy. I am using image surfaces. 

Yes, cairo.d is generated from GI data too and only contains the few symbols and types required to use the other libs. There are other cairo D bindings, which probably could be used with a small glue layer. Making sane cairo bindings is on my to-do list, but I won't have the time for that in the next few weeks.

No hurry, I have GtkD. It's biggest win is that it is considered stable and usable by many for a long time.
 "-ffunction-sections -fdata-sections -Wl,--gc-sections" is a good idea, but I
found it to break exception throwing for my programs.

 GDC/DMD? Would you happen to have a small contained sample that breaks?
 Not garbage collecting sections means executables that are several times
 larger (IIRC for the small gtk example the difference was 1.2M vs 0.3M).

 artur

No example. I don't know what I tried it on, but I remember that I was hunting a bug that occurred, because an important exception wasn't thrown. I think it was a plain old "throw ...". It was with GDC, since DMD doesn't offer a one-section-per-function flag. I can give it a second try. I didn't post any bug reports, since gc-sections is a difficult beast: https://bitbucket.org/goshawk/gdc/issue/293/ffunction-sections-fdata-sections-for https://bugzilla.redhat.com/show_bug.cgi?id=788107 Without support from Iain, I don't expect a bug would be fixed by adding some hack to keep a function from being garbage collected (or whatever caused me problems).

The first bug is about GDC having gc-sections as a *default*, which Iain seems to think isn't important because a) phobos will be a shared library soon and b) it needs testing. I agree with the latter, but the former is wrong - it will be many, many years before even considering using a phobos DLL will be an option (for reasons that i mentioned in #293). The second ticket is about some already fixed upstream binutils bug. I've been running with phobos built using "-ffunction-sections -fdata-sections" since ~ the time of #293 and so far haven't seen any problems (which of course doesn't mean that there aren't any). Preventing a section from being garbage collected could be as simple as adding "KEEP()" around its name in the linker script. But i've failed to reproduce any problems. I'll need to remember to keep adding the options to every app makefile, because so far i often didn't bother to do it... But, at least for exceptions, i wouldn't expect problems, as the C++ case is already handled and GDC uses a similar scheme. artur

Ok, my trust in gc-sections is slowly returning. So far it works as advertised. :) It shaved off ~900 KB, so I am at acceptable 2.2 MB now. LTO is not working for me due to https://bitbucket.org/goshawk/gdc/issue/284/lto-un efined-reference-to . -- Marco
Apr 23 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Mon, 23 Apr 2012 12:00:02 +0200
schrieb Trass3r <un known.com>:

 I've been running with phobos built using "-ffunction-sections  
 -fdata-sections" since ~the time of #293 and so far haven't seen any  
 problems (which of course doesn't mean that there aren't any).

Me too. If you don't use gc-sections there shouldn't be any difference and if you do a lot of unnecessary code is stripped.

Allright, I just built GDC with DFLAGS=-ffunction-sections -fdata-sections You know what happened? My animation in the Gtk app started to stop for some milliseconds in regular intervals. Yes, the application got smaller, but it started to show subtle anomalies, like back when I had the problem with exceptions. :-/ -- Marco
Apr 23 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 23 April 2012 at 11:28:08 UTC, Marco Leise wrote:
 You know what happened? My animation in the Gtk app started to 
 stop for some milliseconds in regular intervals.

Sounds like GC problems. My wild guess without even really thinking about whether it makes sense: The GC now scans a much larger memory region because of an unexpected section layout, leading to the noticeable pauses – which platform are you on? David
Apr 23 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Mon, 23 Apr 2012 17:48:07 +0200
schrieb "David Nadlinger" <see klickverbot.at>:

 On Monday, 23 April 2012 at 11:28:08 UTC, Marco Leise wrote:
 You know what happened? My animation in the Gtk app started to=20
 stop for some milliseconds in regular intervals.

Sounds like GC problems. My wild guess without even really=20 thinking about whether it makes sense: The GC now scans a much=20 larger memory region because of an unexpected section layout,=20 leading to the noticeable pauses =E2=80=93 which platform are you on? =20 David

I suspect the GC as well, but I have no idea what you have in mind. How doe= s the section layout influence the GC? I'm on Linux x86_64. --=20 Marco
Apr 23 2012
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
I did a test run with a system profiler and I see this:

--8<-----------------

CPU: Core 2, speed 2001 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask
of 0x00 (Unhalted core cycles) count 100000

%        symbol name
24.5102  void gc.gcx.Pool.__invariant()
10.4862  void gc.gcx.Gcx.__invariant()

--8<-----------------

invariant()? Wouldn't that be removed in a release build? Then it came to my
head, that maybe, just maybe, setting
export DFLAGS="-ffunction-sections -fdata-sections"
before running make would disable all other flags. ... Yes that was the
problem. Now it is working as expected.

-- 
Marco
Apr 24 2012
prev sibling next sibling parent "timotheecour" <thelastmammoth gmail.com> writes:
Have you tested it on osx?
I get lots of errors such as Error: module Atk from file 
gtk2/atk.d conflicts with another module Atk from file gtk2/atk.d 
etc...
I'm wondering whether it's due to case insensitivity on 
OSX/windows. I thought the convention was to use all lowercase 
for module names. As it is it seems to create collisions. Also 
there were a few other errors which I had tweak for eg:

phobos/std/bitmanip.d(66): Error: shift by 32 is outside the 
range 0..31
phobos/std/bitmanip.d(149): Error: template instance 
std.bitmanip.createAccessors!("_mantissa_low_mantissa_high_biased_exponent_sign",uint,"
antissa_low",32,0u) 
error instantiating
phobos/std/bitmanip.d(203):        instantiated from here: 
createFields!("_mantissa_low_mantissa_high_biased_exponent_sign",0,uint,"mantissa_low",32,uint,"mantissa_high",20,uint,"biased_exponent",11,uint,"sign",1)
.../girtod/gtk2/glib2.d(3528):        instantiated from here: 
bitfields!(uint,"mantissa_low",32,uint,"mantissa_high",20,uint,"biased_exponent",11,uint,"sign",1)



On Sunday, 1 April 2012 at 19:54:31 UTC, Artur Skawina wrote:
 What's new?

  - Now, in addition to

    GLib, GModule, GObject, Gio, GdkPixbuf, Pango, PangoCairo, 
 PangoFT, Gdk, Atk and Gtk+

    there are also bindings for

    Clutter, ClutterX11, Cogl, CoglPango and Mx.

  - Struct inheritance. No more need for 
 "container.add(&vbox.widget);", you can
    write that as just "container.add(vbox);", the compiler will 
 do all the work
    to check if the 'vbox' is somehow derived from 'widget', and 
 convert the
    pointer by itself.

    This works not only for "struct Widget {}; struct VBox { 
 Widget widget; ... };",
    but also for "struct Widget {}; struct VBox { Widget* 
 widget; ... };".
    You can extend built-in widgets and still use them with the 
 std APIs.

 -  Objects can now be constructed as "gtk.VBox(0, 0)";
    the old way, ie "gtk.VBox.new_(0, 0);" still works.

 -  All methods that take a (char*) pointer now also silently 
 accept D strings;
    casting to (char*) and/or calling toStringz are no longer 
 necessary. It will
    be done implicitly every time you try to pass a D string; 
 you can still pass
    a (char*) to avoid the copy.

 -  GTK (GObject) interfaces supported.

 -  Better error messages when registering signal callbacks (the 
 messages given by
    the compiler when a template instantiation fails are not 
 very helpful and, as
    it typically happens via several alias levels, were often 
 just confusing).

 -  Some 64-bit fixes (I don't have a 64-bit GTK stack ATM, so 
 there could be
    more problems around).

 -  The pre-generated D modules were built using newer library 
 versions
    (still GTK2, only the glib version is newer than that).

 -  New examples: Clutter and Mx. Trivial, but enough to get you 
 started.


 A D GTK app now looks like this:

    
 http://repo.or.cz/w/girtod.git/blob/refs/heads/master:/example_gtk.d

 doesn't need a single cast (other than for skipping the string 
 copies, using
 (void*) library APIs and object lookup tricks, all of which 
 could be avoided,
 but I intentionally didn't do this in the example), looks much 
 better than
 the equivalent C version would and couldn't be done any more 
 efficiently in C
 (assuming same compiler middle/backend and ignoring the string 
 differences, as
 for most cases these don't matter. The convenience makes up for 
 the few extra
 copies and these can be avoided in every case where performance 
 really matters).


 The code is here: http://repo.or.cz/w/girtod.git

 The easiest way to try the bindings is probably to check out 
 the "gtk2" branch,
 copy the "gtk2" directory to your app directory and import from 
 there.

 The girtod tool used to generate the D modules lives in the 
 "master" branch.
 When used with different lib versions than the ones I tried it 
 on, it may need
 a few tweaks; sometimes new types appear or move between the 
 libs, new weird or
 broken introspection data shows up etc.

 artur

 PS. Are there any sane Cairo D binding out there? (What's 
 "sane"? Well, if
     there's a "class" in there somewhere then it's not sane)

Jun 01 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/01/12 12:01, timotheecour wrote:
 Have you tested it on osx?

No. You are probably the first person to try it on osx.
 I get lots of errors such as Error: module Atk from file gtk2/atk.d conflicts
with another module Atk from file gtk2/atk.d etc...
 I'm wondering whether it's due to case insensitivity on OSX/windows. I thought
the convention was to use all lowercase for module names. As it is it seems to
create collisions.

Weird, never happened here (linux). All (gtk) D module file names use only lower case ASCII, so case-insensitivity and/or normalization shouldn't cause problems. What are you doing when you get the above error?
 Also there were a few other errors which I had tweak for eg:
 
 phobos/std/bitmanip.d(66): Error: shift by 32 is outside the range 0..31
 phobos/std/bitmanip.d(149): Error: template instance
std.bitmanip.createAccessors!("_mantissa_low_mantissa_high_biased_exponent_sign",uint,"
antissa_low",32,0u) error instantiating
 phobos/std/bitmanip.d(203):        instantiated from here:
createFields!("_mantissa_low_mantissa_high_biased_exponent_sign",0,uint,"mantissa_low",32,uint,"mantissa_high",20,uint,"biased_exponent",11,uint,"sign",1)
 .../girtod/gtk2/glib2.d(3528):        instantiated from here:
bitfields!(uint,"mantissa_low",32,uint,"mantissa_high",20,uint,"biased_exponent",11,uint,"sign",1)

This appears to be a std.bitmanip.bitfields bug. Doesn't happen here. You can just comment out that struct definition to make things compile. (these bitfields are not accessible anyway, because of a girtod bug, which i only noticed now and will fix soon). What compiler/version? artur
Jun 01 2012