# Sharing some thoughts on programming languages and gui toolkits.



## Alain De Vos (Apr 3, 2021)

Here the results of some tests did I with programming languages and gui toolkits,
First what works nicely,
ruby+tk/fox/gtk
python+tk/fltk/wxwidgets/gtk/qt
kotlin(java)+swing
charp+gtk
dlang+tk
dlang+gtk

Second what does not, work or i find ugly:
ada+gtk : ugly
go+gtk : broken
crystal+gtk : broken
nim+gtk : ugly
scala+swing : unsupported

Thought,
Alternative there is electron, popular but needs very much code, even to do something very simple.
I find a mix of html,css,javascript very ugly.
Feel free to elaborate or share your experiences.


----------



## zirias@ (Apr 3, 2021)

Hm, why not C++/Qt (or, if you prefer, C/GTK)? I prefer C over C++, but Qt over GTK, so I end up using C++ for GUI applications.

Nice and perfectly portable (Win, Mac, Linux, *BSD, ...), just without the bullshit attached to electron


----------



## Snurg (Apr 3, 2021)

Perl/Tk: works. But it is sooo retro...


----------



## Menelkir (Apr 3, 2021)

Zirias said:


> Hm, why not C++/Qt (or, if you prefer, C/GTK)? I prefer C over C++, but Qt over GTK, so I end up using C++ for GUI applications.
> 
> Nice and perfectly portable (Win, Mac, Linux, *BSD, ...), just without the bullshit attached to electron


Theres also x11-tolkits/fox17 to work with C++. Also x11-tolkits/open-motif, because why not?


----------



## BostonBSD (Apr 4, 2021)

I was going to post this somewhere else, but then I saw this.
I just learned how to make a really easy gui perl script with gtk3.
[any command line script can have a gui really really easily.]

This is an example script that gets the system time and sets it on a label.
I modified some code from a tutorial found here


```
#!/usr/local/bin/perl
#Most of this code comes from a tutorial posted @ https://github.com/kevinphilp/Perl-gtk3-Tutorial
use strict;
use warnings;
use diagnostics;
use feature ':5.14';
use Gtk3 '-init';
use Glib qw/TRUE FALSE/;

#######Declarations

my $window = Gtk3::Window->new('toplevel'); #Creates a toplevel window
$window->set_title("Example Title"); #Sets the title
$window->set_position("center"); # Sets the starting location
$window->set_default_size(400, 300); # Sets the initial size
$window->set_border_width(5);
$window->signal_connect (delete_event => sub { Gtk3->main_quit }); #Exits Program When the Window Closes

my $button1 = Gtk3::Button->new("Quit"); #create a button
$button1->signal_connect(clicked => \&quit_function); #give the button functionality.
my $button2 = Gtk3::Button->new("Say Hello"); #create a button
$button2->signal_connect(clicked => \&say_something, "Hello"); #call a function, pass a string to the function.
my $button3 = Gtk3::Button->new("Get Time"); #create a button
$button3->signal_connect(clicked => \&get_time); #call a function.

my $hbox = Gtk3::Box->new("horizontal",5); #create a container for the buttons, the items are stacked horizontally, 5 pixels between them
$hbox->set_homogeneous (TRUE); #Allocate the same amount of space to each item, now all items are the same width.
$hbox->pack_start($button1, TRUE, TRUE, 0); #add a button to the container, expand the container to make space for the item, the expansion is filled with the item and not padding, 0 extra pixels of padding
$hbox->pack_start($button2, TRUE, TRUE, 0);
$hbox->pack_start($button3, TRUE, TRUE, 0);

my $vbox = Gtk3::Box->new("vertical",5); #create a container with items stacked vertically.
$vbox->add($hbox); #add the hbox container to the vbox container
my $label = Gtk3::Label->new("Am I connected?"); # create a label
$vbox->add($label);#add the label to the vbox container.

$window->add($vbox); #Add the vbox container to the main window.
$window->show_all; #Makes the window visible.

######functions
sub say_something {
    my ($button,$userdata) = @_;
    $label->set_label( $userdata );
    return TRUE;
}

sub get_time {
    my $time = `date \"+%r\"`; #get the system time.
    $label->set_label( $time ); # set the label
    return TRUE;
}

sub quit_function {
    say "Exiting Gtk3"; #say is no different from print
    Gtk3->main_quit;
    return FALSE;
}
############

Gtk3->main; #Tells perl to wait for user input.
```


----------



## Alain De Vos (Apr 4, 2021)

I never really used perl. I tried your script, it returns " Can't locate Gtk3.pm @ INC"


----------



## eternal_noob (Apr 4, 2021)

Alain De Vos said:


> I find a mix of html,css,javascript very ugly.


It all depends on your CSS. 


Zirias said:


> Hm, why not C++/Qt (or, if you prefer, C/GTK)?


This.


----------



## Snurg (Apr 4, 2021)

Alain De Vos said:


> I never really used perl. I tried your script, it returns " Can't locate Gtk3.pm @ INC"


`cpan Gtk3`

see here


----------



## BostonBSD (Apr 4, 2021)

Alain De Vos said:


> I never really used perl. I tried your script, it returns " Can't locate Gtk3.pm @ INC"


The Gtk3 and Glib modules need to be installed.

`sudo cpan install Glib Gtk3`

I'd like to find a tutorial for C/C++ and Gtk3 next.

I always like having at least one compiled language and one interpreted language ready.
Java is really useful for socket programming, but I still prefer C/C++ and Perl [python seems nearly equivalent to perl].

I would also keep my eye on rust.  It has much greater ability to prevent garbage cleanup errors and seems to have nearly the same performance as C/C++ [this is an edit, but whatever benefits are found in other languages probably will make their way to C/C++ standardization eventually, rust compile time is reportedly longer with larger binaries].

If a language I already know can do it, that's better than using a language I do not already know [unless it become prohibitivly expensive to keep using the same language, which is why I would use java for sockets].


----------



## eternal_noob (Apr 4, 2021)

BostonBSD said:


> Java is really useful for socket programming, but I still prefer C/C++ and Perl.


A pretty decent library for socket programming with C++ is Asio.


----------



## ProphetOfDoom (Apr 5, 2021)

I love gtk+ it’s a superb piece of engineering and an absolute pleasure to work with. A good book focusing on C is “Foundations of Gtk+ Development” by Andrew Krause. I got it about ten years ago but it’s still surprisingly relevant. Occasionally you’ll get a deprecated function but Gtk+ is very good at warning you about these.


----------



## Jose (Apr 5, 2021)

BostonBSD said:


> The Gtk3 and Glib modules need to be installed.
> 
> `sudo cpan install Glib Gtk3`


I'd rather use the package or the port





						FreshPorts -- x11-toolkits/p5-Gtk3: Perl module for Gtk+ 3.x graphical user interface library
					

Perl bindings to the 3.x series of the gtk+ toolkit. This module allows you to write graphical user interfaces in a Perlish and object-oriented way, freeing you from the casting and memory management in C, yet remaining very close in spirit to original API. Find out more about gtk+ at...




					www.freshports.org
				




I'm allergic to running these platform-specific package managers as root, and having them pee all over my filesystems.


----------



## BostonBSD (Apr 5, 2021)

Jose said:


> I'd rather use the package or the port
> 
> 
> 
> ...


I never even considered that.  I never knew that was a problem.


----------



## Beastie7 (Apr 5, 2021)

AlexanderProphet said:


> I love gtk+ it’s a superb piece of engineering and an absolute pleasure to work with. A good book focusing on C is “Foundations of Gtk+ Development” by Andrew Krause. I got it about ten years ago but it’s still surprisingly relevant. Occasionally you’ll get a deprecated function but Gtk+ is very good at warning you about these.


 
You can't be serious.


----------



## garry (Apr 6, 2021)

Alain De Vos said:


> Here the results of some tests did I with programming languages and gui toolkits,
> First what works nicely,
> ...
> python+qt : One of the rare qt bindings which works fine.


python+Qt:  I'm coming around to agree with this one.  I installed helloSystem / FreeBSD 13 and the interface achieved with Qt and Python is impressive in its simplicity and usability. I think probono is on to something good there.


----------



## Alain De Vos (Apr 7, 2021)

Qt has some very interesting widgets not found in Gtk. I find it superior, but it's language bindings are poor. So for Qt there is only C++ or Python.
I wonder will fox, fltk, wxwidgets survive as toolkits, or die ?


----------



## eternal_noob (Apr 7, 2021)

Alain De Vos said:


> I wonder will fox, fltk, wxwidgets survive as toolkits, or die ?


I use wxWidgets all the time, it's a very good library. I don't think it will die soon. Last commit was an hour ago.
Don't know about the others.


----------



## BostonBSD (Apr 8, 2021)

Here's a C program that does exactly the same thing as that perl script {I just learned this, i figured I'd post it}.  Perl is faster and easier to program, perhaps not as efficient though.



```
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


GtkBuilder *builder;

static void
print_time (GtkWidget *widget,
             gpointer   data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1"); //get the label1 GObject from the builder
   
    ///////////////////////////////////////Run A Command and Get the Output
    FILE *file_pointer;
    char variable[256];

    /* Open the command for reading. */
    file_pointer = popen("/bin/date \"+%r\"", "r");
    if (file_pointer == NULL) {
        printf("Didn't Work\n" );
        exit(1);
    }

    // Read in one line of file_pointer to variable
    fgets(variable, sizeof(variable), file_pointer);
     /* close */
    pclose(file_pointer);
    ///////////////////////////////////////I found this portion from a bing search.
   
    //set the label.
    g_object_set (label,"label",variable,NULL);  //a GObject, Property Name, Property Value, NULL indicates no further properties to parse.

 
}

static void
print_hello_label (GtkWidget *widget,
             gpointer   data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1");
    g_object_set (label,"label","Hello World!",NULL);
}

int
main (int   argc,
      char *argv[])
{
  GObject *window;
  GObject *button;
  GError *error = NULL;

  gtk_init (&argc, &argv);

  /* Construct a GtkBuilder instance and load our UI description */
  builder = gtk_builder_new ();
  if (gtk_builder_add_from_file (builder, "builder.ui", &error) == 0)
    {
      g_printerr ("Error loading file: %s\n", error->message);
      g_clear_error (&error);
      return 1;
    }

  /* Connect signal handlers to the constructed widgets. */
  window = gtk_builder_get_object (builder, "window");
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  button = gtk_builder_get_object (builder, "button1");
  g_signal_connect (button, "clicked", G_CALLBACK (print_time), NULL);

  button = gtk_builder_get_object (builder, "button2");
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello_label), NULL);

  button = gtk_builder_get_object (builder, "quit");
  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);

  gtk_main ();

  return 0;
}
```

The user interface is setup with an XML file, it should be called "builder.ui" and in the same directory as the binary file.



```
<interface>
  <object id="window" class="GtkWindow">
    <property name="visible">True</property>
    <property name="title">Grid</property>
    <property name="window-position">center</property>
    <property name="default-width">400</property>
    <property name="default-height">300</property>
    <property name="border-width">5</property>
    <child>
    <object id="vbox" class="GtkBox">
        <property name="homogeneous">True</property>
        <property name="visible">True</property>
        <property name="orientation">vertical</property>
        <property name="vexpand-set">True</property>
        <property name="vexpand">True</property>
        <child>
        <object id="hbox" class="GtkBox">
            <property name="homogeneous">True</property>
            <property name="visible">True</property>
            <property name="orientation">horizontal</property>
            <property name="hexpand-set">True</property>
            <property name="hexpand">True</property>
            <child>
            <object id="button1" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Get Time</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
            <child>
            <object id="button2" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Say Hello</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
            <child>
            <object id="quit" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Quit</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
        </object>
        <packing>
        </packing>
        </child>
        <child>
        <object id="label1" class="GtkLabel">
            <property name="visible">True</property>
            <property name="label">Am I Connected?</property>
        </object>
        </child>
    </object>
    <packing>
    </packing>
    </child>
  </object>
</interface>
```


To Compile:
`gcc `pkg-config --cflags gtk+-3.0` -o gtk_example gtk_example.c `pkg-config --libs gtk+-3.0``

assuming the source file is called "gtk_example.c"

I don't really think it matters what the language is, all that matters is the gui library.  GTK and QT look the same no matter if it's C, C++, Python or Perl....so far as I can tell.


----------



## zirias@ (Apr 8, 2021)

I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically  But then, I guess GTK would support that as well. Anyways, BostonBSD, this tiny example looks pretty readable and self-explanatory. Maybe I should give GTK another look, it's intriguing to have a GUI in plain C. Last time I did that, it was for Windows, using native win32 API. Now, THAT's really mind-boggling


----------



## BostonBSD (Apr 8, 2021)

Zirias said:


> I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically  But then, I guess GTK would support that as well. Anyways, BostonBSD, this tiny example looks pretty readable and self-explanatory. Maybe I should give GTK another look, it's intriguing to have a GUI in plain C. Last time I did that, it was for Windows, using native win32 API. Now, THAT's really mind-boggling


I saw that it can be built in programmatically from the gtk website, although they suggested using an XML file if only because the UI can be changed after compile time if need be [its also possible to compile the XML data into the binary as a string].  They also said something about using glade to design your own UI, which then generates its own XML file.

It is really intriguing that a GUI can be made in plain C. Thanks for the nice comments  .


----------



## kpedersen (Apr 8, 2021)

Zirias said:


> I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically



Agreed. There is the argument for not mixing controller, view and model. However my response to that is yes, but there is no reason to use a different language or markup in doing so.

I am quite a big fan of wxWidgets. The fact that it abstracts many other toolkits means that it will likely have a very good lifespan. I.e it gets "free" Wayland support by proxy of supporting Gtk+ as a backend.


----------



## Phishfry (Apr 8, 2021)

I was surprised to see wxWidgets not on the OP's list.
devel/wxformbuilder is easy enough for a novice like me to slap together a basic graphical application..

What about editors/komodo-edit and tcl...

Also x11-toolkits/fox17 as suggested above.


----------



## Alain De Vos (Apr 8, 2021)

I trie to avoid xml & editors/guis/builders.
Any ideas on dart ? or swt/eclipse ?

Something else. Here a ruby+fox toolkit fahrenheit to celcius converter,

```
#!/usr/local/bin/ruby
require 'fox16'
include Fox

class MyMainWindow < FXMainWindow
    def initialize(app)
        super(app, "Convertor", :width => 400, :height => 200)
        entry=FXTextField.new(self,20)
        button=FXButton.new(self, "Convert")
        label=FXLabel.new(self, "_________")
    
        button.connect(SEL_COMMAND) do
            fs=entry.text
            f=fs.to_f
            c=(f-32.0)*5.0/9.0
            cs=c.to_s
            label.text=cs
        end
    end

    def create
        super
        show(PLACEMENT_SCREEN)
    end
end

if __FILE__ == $0
    FXApp.new do |app|
        MyMainWindow.new(app)
        app.create
        app.run
    end
end
```


----------



## zirias@ (Apr 8, 2021)

kpedersen said:


> Agreed. There is the argument for not mixing controller, view and model. However my response to that is yes, but there is no reason to use a different language or markup in doing so.


Well about that: I think MVC is a great concept for dealing with web applications, cause, if your rendering target (the browser) expects markup, it comes naturally to use markup to describe your view. Still I prefer implementations that actually _compile_ these views and link them to the binary. For "desktop" UIs, I'm fine with just the dusty old presentation layer done in code. Business logic is clearly separated in any case, enough separation of concerns for me 



kpedersen said:


> I am quite a big fan of wxWidgets. The fact that it abstracts many other toolkits means that it will likely have a very good lifespan. I.e it gets "free" Wayland support by proxy of supporting Gtk+ as a backend.


IMHO having yet another abstraction layer was more useful in the past, nowadays I see little reason not to use Qt or GTK directly, as both support lots of "native" display solutions on many platforms…


----------



## kpedersen (Apr 8, 2021)

Zirias said:


> IMHO having yet another abstraction layer was more useful in the past, nowadays I see little reason not to use Qt or GTK directly, as both support lots of "native" display solutions on many platforms…



Qt is pretty stable (Though MOC still makes me shudder) but Gtk I don't really want to be updating every ~5 years. I am maintaining a version of GtkRadiant and am still stuck at Gtk+2.x because of a large number of changes required to update it to the latest (actually half way through porting it to wxWidgets ).


----------



## BostonBSD (Apr 8, 2021)

I tried the ruby script, it only takes 33 lines of code and looks super simple.  
The interface doesn't look as pretty as gtk, although that might not matter.


----------



## Alain De Vos (Apr 9, 2021)

Just as show-off a compiled dlang+tk toolkit program doing a fahrenheit  convertor,

```
import tkd.tkdapplication;                               // Import Tkd.
import std.conv;

class MyTkdApplication : TkdApplication{     // Extend TkdApplication.
    Frame frame;
    Entry entry;
    Button button;
    Label label;
    Button exitButton;

    private void exitCommand(CommandArgs args){  // Create a callback.
        this.exit();                                                            // Exit the application.
    }

    private void buttonPressed(CommandArgs args){  // Create a callback.
        string fs=entry.getValue();
        float f=to!float(fs);
        float c=(f-32.0)*5.0/9.0;
        string cs=to!string(c);
        label.setText(cs);
    }

    override protected void initInterface(){             // Initialise user interface.
   
        frame = new Frame(2, ReliefStyle.groove)         // Create a frame.
            .pack(10);                                   // Place the frame.

        entry = new Entry(frame)   // Create a entry.
            .pack(10);                       // Place the entry.

        button = new Button(frame, "Convert ")   // Create a button.
            .setCommand(&this.buttonPressed)    // Use the callback.
            .pack(10);                                   // Place the button.

        label = new Label(frame, "____________")  // Create a label.
            .pack(10);                                   // Place the label.

        exitButton = new Button(frame, "Exit")    // Create a button.
            .setCommand(&this.exitCommand)    // Use the callback.
            .pack(10);                                   // Place the button.
    }
}

void main(string[] args){
    auto app = new MyTkdApplication(); // Create the application.
    app.run();                                           // Run the application.
}
```


----------



## jmos (Apr 10, 2021)

The same in Tcl/Tk would look like this (done in 5 minutes):

```
#!/usr/local/bin/wish8.6

proc myresult {} {
    .f.r configure -text [ expr ([ .f.v get ] - 32.0) * 5.0 / 9.0 ]
}

frame  .f -relief groove -borderwidth 2 -pady 10 -padx 10
entry  .f.v
button .f.c -text "Convert" -command myresult
label  .f.r -text "____________"
button .f.q -text "Exit" -command exit
pack   .f.v .f.c .f.r .f.q -pady 10 -padx 10
pack   .f -pady 10 -padx 10
```
(Misses - like the "original" - input/error handling, window resizing, any aligns/expands for the widgets, infos for the window manager etc. - and uses the old style Tk toolkit… and maybe much more that should be done before it's a program for the people.)


----------



## hruodr (Apr 10, 2021)

jmos said:


> The same in Tcl/Tk would look like this (done in 5 Minutes):


Tk, an extension of tcl, was mentioned many times in conjunction with other scripting languages, 
but you were the first mentioning tcl. Why?


----------



## jmos (Apr 10, 2021)

hruodr said:


> Tk, an extension of tcl, was mentioned many times in conjunction with other scripting languages,
> but you were the first mentioning tcl. Why?


I love Tcl (and Tk) for its simple, but powerfull and complete command syntax - just a few commands can do anything. It's rock solid since ever, platform independent since ever (even when it comes to file paths, accessing fonts etc.), and: still alive (!).

If you used and liked Tcl: No matter what you try later, compared to Tcl everything is kind of … half-hearted, cumbersome, contructed… just not up to scratch, leaves you with the feeling "hm, that's not the real thing"…

The only thing missing: A clever handling of multidimensional, associative arrays (the way like PHP offers); In Tcl you often use lists, which I don't really use in other programming languages anymore.

Much of my daily work environment and tools I wrote myself in Tcl (/Tk): Offering / invoicing / accounting software (Tcl/Tk is often named "just for small apps", but you can do real huge and complex stuff as well), programming environment (!), time tracking + calendar + todo list, a style engine for Garmin GPS devices (used for self made hiking maps), mass rename & time adjust (to merge more than one cameras photos/videos from a trip into one sorted directory), (un)mounting any storages/disk, get the weather forecast (into conky), my alterantive to a spreadsheets, backup tool (has to be as comfortable as possible, otherwise no enduser do backups), combine many PDFs into one via GUI, tea timer in system tray, battery status of my mouse as tray icon, wine cellar management, creating audio playlists for my DLNA server, view installed fonts, and even my website is dynamic driven by Tcl… Just to name a few of these tools


----------



## hruodr (Apr 10, 2021)

jmos said:


> my alterantive to a spreadsheets


Tcl combines best with sqlite3, for example for using the db as file format for your own application.


----------



## kpedersen (Apr 10, 2021)

I quite like Tk in terms of how its layout manager works.

However I wish there was a proper libtk library to use from C or C++. Being tied to Tcl means I can't use it for almost any of my projects. I would end up spending too long having to write bindings against all the other native middleware I use.


----------



## hruodr (Apr 10, 2021)

kpedersen said:


> I would end up spending too long having to write bindings against all the other native middleware I use.


I do not think you must bind to all that. Tcl/tk C-API allow your C program to run tcl/tk scripts.


----------



## kpedersen (Apr 10, 2021)

hruodr said:


> I do not think you must bind to all that. Tcl/tk C-API allow your C program to run tcl/tk scripts.


If you go that way round instead, those tcl/tk scripts will need to then call back into the C / C++ code (i.e on a button click). So you will end up indirectly having to make tcl bindings for your own software.

If you look around the internet, you will see that most tcl/tk documentation misses this part off "conveniently" because they know it is awkward.

The closest we have to a proper C++/tk binding is cpptk (http://cpptk.sourceforge.net/) but that has been unmaintained for years.


----------



## hruodr (Apr 10, 2021)

kpedersen said:


> So you will end up indirectly having to make tcl bindings for your own software.


But I think it is no catastrophe.

There are two approachs: (1) C calls an interpreter that run tcl/tk code, some variables are exchanged between
C and the interpreter. (2) You extend tcl/tk with your C routines, and continue programming in tcl (main = tclsh main).


----------



## kpedersen (Apr 10, 2021)

hruodr said:


> some variables are exchanged between


This is the tricky bit. Consider if you have to exchange an OpenSSL BIO or some composite type (like a struct). You can't pass those between language boundaries. If you try, you will need to describe the layout in both languages.
Also the difficulty is memory, if you hold onto a tcl object, you don't know the lifespan within the C or C++.

Likewise in C++ RAII might strip out the data (i.e when the std::shared_ptr<T> goes out of scope) so tcl is holding onto a dangling pointer.

Bindings are complex beasts. Bringing multiple languages into a project is non-trivial. Especially for something that is trivial like a GUI.


----------



## Alain De Vos (Apr 10, 2021)

Bindings are indeed complex. Qt only binds to python or C++.
Gtk has introspection this is a serious advantage.


----------



## hruodr (Apr 10, 2021)

kpedersen said:


> Consider if you have to exchange an OpenSSL BIO


But the idea is to use tcl/tk only for bulding the GUI, for configuration scripts, mainly for interaction with the user.


----------



## kpedersen (Apr 10, 2021)

hruodr said:


> But the idea is to use tcl/tk only for bulding the GUI, for configuration scripts, mainly for interaction with the user.


Oh right. I tend to write GUI programs that need to do a little more than that. If it is just for simple configuration, then perhaps Zenity or CDialog is good enough.


----------



## hruodr (Apr 10, 2021)

kpedersen said:


> I tend to write GUI programs that need to do a little more than that.


More than GUI is written in C  with complex structures, the GUI in tcl/tk.

Or does "GUI programs" mean that the main functionality of the program is written in Xlib?!

And with configuration I also mean customization.

BTW. This was the original idea of tcl/tk. Later it began to be used as a scripting language to write
applications.


----------



## kpedersen (Apr 10, 2021)

hruodr said:


> Or does "GUI programs" mean that the main functionality of the program is written in Xlib?!


Not necessarily Xlib but the main functionality of the program is often written entirely in C or C++.

The main bindings of Tk that are in common use are Perl (Perl/Tk) and Python (Tkinter). You will see with these you stick to Perl or Python for 100% of the program and you don't need to start injecting tcl scripts into the code and marshaling between data types.

These bindings are interesting because they are both done very differenty. Perl/Tk opted to directly bind against the underlying Tk C API which is very low level (actually lower level than Xlib). Whereas Tkinter instead uses tcl as an intermediate behind the scenes to tap into Tk. Both work quite effectively if your project doesn't depend on native C or C++.


----------



## hruodr (Apr 10, 2021)

kpedersen said:


> The main bindings of Tk that are in common use are Perl (Perl/Tk) and Python (Tkinter).


And you can bind tcl/tk in your own applications: hence, main functionality in C.

As said, this was the now almost forgotten original idea of tcl that is perhaps alive in lua. I quote a well know
tcl textbook:



> Tcl  is  implemented  in  a  C  library  that is easy to integrate into an existing application. By adding the Tcl interpreter to your application, you can configure and control it with Tcl scripts, and with Tk you can provide a nice graphical interface to it. This was the original model for Tcl. Applications would be largely application-specific C code and include a small amount of Tcl for configuration and the graphical interface. However, the basic Tcl  shells  proved  so  useful  by  themselves  that  relatively  few  Tcl  programmers need to worry about programming in C or C++.





			http://www.beedub.com/book/3rd/Cprogint.pdf
		


The approach in the middle is to program critical things in C, extend tcl with that, and continue 
programming in tcl.


----------



## chrbr (Apr 10, 2021)

hruodr said:


> And you can bind tcl/tk in your own applications: hence, main functionality in C.
> 
> As said, this was the now almost forgotten original idea of tcl that is perhaps alive in lua. I quote a well know
> tcl textbook:
> ...


I really love that book. It enabled me in starting with Tcl very quick. At that time I have had to do a lot realted to automatic tests using signal generators, spectrum anaylsers and that kind of stuff. Tcl8.4 has been up to date and with the installation of the company ActiveState it was easy to start with, even on Windows.

The most fancy thing I have done in the past has been about audio processing. I hace used snack to get that data, FFTW for spectral analysis and some post processing for filtering and waterfall diagramms. The GUI and the things around have been Tcl/Tk code. I have interfaced snack, FFTW and some self written part for the waterfall stuff in C. For that your book has been extremly helpful. I am not a software engineer and even on C on a very low level. But with Tcl/Tk and your book this was possible for me.

Tcl/Tk might have an outdated image. But it is outstanding if it is about in making a tool with a GUI with very little effort in almost no time.


----------



## kpedersen (Apr 10, 2021)

hruodr said:


> And you can bind tcl/tk in your own applications: hence, main functionality in C.


Heh yes but don't forget Perl and Python bindings have had teams spending decades on developing these bindings. It is too much for smaller projects.

Give it a shot and you will see what I mean. My prediction is that the code will be around 5x more than a standard C++ UI library. You will also lose most of the type safety.


----------



## hruodr (Apr 11, 2021)

kpedersen said:


> Perl and Python bindings have had teams spending decades on developing these bindings. It is too much for smaller projects.


But they were not only making a widget for their programs, you have complete control of Tk in perl and python.

With extending I experimented a little and it is really easy, as chrbr noted. I cannot imagine that only 
embedding is such a problem, I must try it more. But yes, since tcl evolved to a full scripting language, 
the footprint may be bigger than a standard UI library. In C there is no much type safety to loss with a C library.


----------



## kpedersen (Apr 11, 2021)

hruodr said:


> you have complete control of Tk in perl and python.


This is very much something I would like with C or C++. These bindings demonstrate that the market is there or they would not have gone through the effort of binding. Instead these communities could have just recommend using tcl from within Perl or Python directly.



hruodr said:


> In C there is no much type safety to loss with a C library.


So many other binding layers (i.e Java's JNI or Lua) present you with a void * which you need to do an unsafe cast to the correct type. This is certainly something I want to avoid. In large programs it is very difficult to keep track of with some pretty nasty results in terms of debugging time.

And with C++ a void * is useless, you can't put that in a std::shared_ptr<T> or you will end up with two separate ref counts that will always result in a double delete. You instead need a large amount of code to "discover" the original ref count container.


----------



## hruodr (Apr 11, 2021)

kpedersen said:


> Instead these communities could have just recommend using tcl from within Perl or Python directly.


And then people would have begun using tcl instead of perl or python. It is really a joke that
tkinter needs to put the whole tcl/tk hidden in python for not programming GUIs directly with it,
but through python. A very good reason to use tcl instead of python.

In an extended tcl or in an application with embedded tcl one will use in any case tcl,
no need to disguise tcl/tk commands as commands in other language, as perl/python
need to do.



kpedersen said:


> This is very much something I would like with C or C++.


Then you do not need a GUI, but a new widget toolkit?!

Tk has a problem: it does not support full unicode, you cannot represent arabic with diacritic signs
over the letters. I really have no much experience with GUI programming except with tk, I
programmed once a very simple program just for showing text with gtk, more simple is impossible:
it was very confuse and non natural.


kpedersen said:


> So many other binding layers (i.e Java's JNI or Lua)



If you put there the whole tcl, for what do you need lua or java?!


----------



## hruodr (Apr 11, 2021)

kpedersen said:


> . Consider if you have to exchange an OpenSSL BIO or some composite type (like a struct). You can't pass those between language boundaries. If you try, you will need to describe the layout in both languages.


BTW, if you insist on dealing with complex structures, see clientData here:





__





						Tcl_CreateObjCommand manual page - Tcl Library Procedures
					





					www.tcl.tk
				




And for a concise introduction on extending tcl, see here:









						tclx/ObjCmdWrite.3 at master · flightaware/tclx
					

Official home of the TclX extension for Tcl. Contribute to flightaware/tclx development by creating an account on GitHub.




					github.com


----------



## kpedersen (Apr 11, 2021)

hruodr said:


> https://github.com/flightaware/tclx/blob/master/doc/ObjCmdWrite.3


Whilst it does look to have nicer FFI facilities than a lot of scripting layers, can you see here the unsafe cast (4th parameter)? https://github.com/flightaware/tclx/blob/master/doc/ObjCmdWrite.3#L396
Casting that back from ClientData is actually where the risk will come from.

The last parameter is also particularly awkward; that is the delete / finalizer function pointer. It will unfortunately work against C++ RAII and instead you will have to manually "pin" data to not be cleaned up. Even C middleware would be problematic because you don't always get to control the lifespan of things.

It just doesn't seem suitable for a number of use-cases. Possibly what has contributed towards a decline of Tk usage with C or C++. Of course these issues can all be worked around but it will be much more work than using a C or C++ toolkit.

For a little more info (because it is an interesting problem!), check out the Tcl Wiki page which also explains why embedding Tcl just to use Tk in a C++ application is not a good approach:





__





						Why adding Tcl calls to a C/C++ application is a bad idea
					

Tclers wiki




					wiki.tcl-lang.org


----------



## hruodr (Apr 11, 2021)

kpedersen said:


> can you see here the unsafe cast (4th parameter)?





kpedersen said:


> The last parameter is also particularly awkward; that is the delete / finalizer function pointer.


As far as I know, ClientData type is void*. And the pointer is passed to the function callback when the
function is called in a script. The finalizer is for treating client data on delete.

I have the impression that these kind of things are unavoidable in C and that you see it from a C++ perspective.

I have no idea of C++, and my C programs look like FORTRAN IV. What can I say?!

In any case, your quoted wiki page is interesting. But the thema there is embedding vs extending.


----------



## BostonBSD (May 9, 2021)

For anyone using these as examples in the future:  This is the same program I posted earlier, except the user interface is compiled inline as a string with the source code (rather than loaded in at runtime from an XML file).

[The easiest way to do this is to generate the UI as a glade {XML} file from glade, then replace all " with \" and remove all newline characters {i used the kate text editor to replace \n with nothing (a literal nothing, not a space or a \0 null character)}.  Copy the result into the source code, as seen below.]



```
//clang `pkg-config --cflags gtk+-3.0` -o gtk_example gtk_example.c `pkg-config --libs gtk+-3.0`
//can also use gcc
//This command won't work in the fish shell, use a different shell.

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


GtkBuilder *builder;

static void print_time (GtkWidget *widget, gpointer data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1"); //get the label1 GObject from the builder

    ///////////////////////////////////////Run A Command and Get the Output
    FILE *file_pointer;
    char variable[256];

    /* Open the command for reading. */
    file_pointer = popen("/bin/date \"+%r\"", "r");
    if (file_pointer == NULL) {
        printf("Didn't Work\n" );
        exit(1);
    }

    // Read in one line of file_pointer to variable
    fgets(variable, sizeof(variable), file_pointer);
     /* close */
    pclose(file_pointer);
    ///////////////////////////////////////I found this portion from a bing search.

    //set the label.
    g_object_set (label,"label",variable,NULL);  //a GObject, Property Name, Property Value, NULL indicates no further properties to parse.


}

static void print_hello_label (GtkWidget *widget, gpointer data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1");
    g_object_set (label,"label","Hello World!",NULL);
}

int main (int   argc, char *argv[])
{
  GObject *window;
  GObject *button;
  GError *error = NULL;

///////////////////////////
  const char ui_string[] = "<interface><object id=\"window\" class=\"GtkWindow\"><property name=\"visible\">True</property><property name=\"title\">Grid</property><property name=\"window-position\">center</property><property name=\"default-width\">400</property><property name=\"default-height\">300</property><property name=\"border-width\">5</property><child><object id=\"vbox\" class=\"GtkBox\"><property name=\"homogeneous\">True</property><property name=\"visible\">True</property><property name=\"orientation\">vertical</property><property name=\"vexpand-set\">True</property><property name=\"vexpand\">True</property><child><object id=\"hbox\" class=\"GtkBox\"><property name=\"homogeneous\">True</property><property name=\"visible\">True</property><property name=\"orientation\">horizontal</property><property name=\"hexpand-set\">True</property><property name=\"hexpand\">True</property><child><object id=\"button1\" class=\"GtkButton\"><property name=\"visible\">True</property><property name=\"label\">Get Time</property></object><packing><property name=\"expand\">True</property></packing></child><child><object id=\"button2\" class=\"GtkButton\"><property name=\"visible\">True</property><property name=\"label\">Say Hello</property></object><packing><property name=\"expand\">True</property></packing></child><child><object id=\"quit\" class=\"GtkButton\"><property name=\"visible\">True</property><property name=\"label\">Quit</property></object><packing><property name=\"expand\">True</property></packing></child></object><packing></packing></child><child><object id=\"label1\" class=\"GtkLabel\"><property name=\"visible\">True</property><property name=\"label\">Am I Connected?</property></object></child></object><packing></packing></child></object></interface>";
///////////////////////////

  gtk_init (&argc, &argv);

  /* Construct a GtkBuilder instance and load our UI description */
  builder = gtk_builder_new ();
  //if (gtk_builder_add_from_file (builder, "builder.ui", &error) == 0)
  if (gtk_builder_add_from_string (builder, ui_string, strlen(ui_string), &error) == 0)
    {
      g_printerr ("Error loading ui_string: %s\n", error->message);
      g_clear_error (&error);
      return 1;
    }

  /* Connect signal handlers to the constructed widgets. */
  window = gtk_builder_get_object (builder, "window");
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  button = gtk_builder_get_object (builder, "button1");
  g_signal_connect (button, "clicked", G_CALLBACK (print_time), NULL);

  button = gtk_builder_get_object (builder, "button2");
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello_label), NULL);

  button = gtk_builder_get_object (builder, "quit");
  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);

  gtk_main ();

  return 0;
}
```


----------



## astyle (May 12, 2021)

Alain De Vos said:


> Qt only binds to python or C++.


Not true. It also has ruby and perl bindings, and java bindings as well. And this is just cursory knowledge from using makefiles to compile KDE and related ports.

Oh, and is there a difference between a 'binding' and an 'API'? I get the impression that they're used interchangeably, but there's gotta be something that differentiates the two.


----------



## Alain De Vos (May 13, 2021)

Ruby binding is discontinued. API is a list of function you can call.


----------



## astyle (May 13, 2021)

Alain De Vos said:


> Ruby binding is discontinued. API is a list of function you can call.


I know what API is... what I want to know is how is that different from a 'binding'. 
As a toolkit, Qt was originally written in C++. Can someone please confirm/correct for me what I'm thinking: 'binding' is some extra code inside the Qt toolkit, that needs to be there in compiled form, so that it's possbile for Qt's 'public' API to be called from a program written in a language other than C++.


----------



## zirias@ (May 13, 2021)

astyle said:


> I know what API is... what I want to know is how is that different from a 'binding'.


A "binding" is typically an API adapter closing a "language gap". In case of Qt, the native API is for C++. So, anything offering an API for a different language by "proxying" to the original C++ API would be called a "binding".


----------



## kpedersen (May 13, 2021)

In practice, everything important is pretty much written in C or C++. As such, if you want to use another language, you need to be able to call into the compiled native C/C++ binary (usually a .so or .dll) and marshall data between your languages inbuilt data types.

Writing and (in particular) maintaining bindings is a very time consuming task so a number of project have ways of generating these bindings from the C/C++ header files or other meta data. Swig, Rust's Bindgen and Perls Xs are common ways.

Some libraries (such as Gtk) actively design their API in a way to help bindings. I.e less callbacks and using opaque data types (pointers to structures are easier to marshall than the structures themselves). I think Qt is attempting to do similar, but the fact it is written in C++ rather than C and has this weird MOC preprocessor layer is making this tricky to maintain.


----------



## Alain De Vos (May 13, 2021)

Or wrapper. You call a function in your language X. And the wrapper calls the library function of the toolkit.
Gtk has introspection. Making it easier to write bindings then Qt.


----------



## zirias@ (May 13, 2021)

kpedersen said:


> I think Qt is attempting to do similar, but the fact it is written in C++ rather than C and has this weird MOC preprocessor layer is making this tricky to maintain.


It's manual work for sure. I'd love to see a "C binding" for Qt  Would be perfectly possible, but definitely a lot of work to maintain. I once tried (in a toy project) to define a simple GUI C API myself and had two backends for it, win32 and Qt. Well, it could display _something_ (a window, some buttons, labels, etc), but I abandoned it soon 

edit, "disclaimer": I'm really not a fan of C++, I think it's an ill-designed language. But the "Qt-flavor" of it is IMHO pretty ok (you can completely disable exceptions without any problems, and it adds something useful with signals/slots – slots playing especially nice with the newer C++-feature of lambdas).


----------



## Menelkir (May 13, 2021)

Zirias said:


> It's manual work for sure. I'd love to see a "C binding" for Qt  Would be perfectly possible, but definitely a lot of work to maintain. I once tried (in a toy project) to define a simple GUI C API myself and had two backends for it, win32 and Qt. Well, it could display _something_ (a window, some buttons, labels, etc), but I abandoned it soon


Let me guess, maintaining bindings for those things is overcomplicated because they have 80% of things that the main developer thought that could be "used later" but in practice will never be used, but is so tangled inside that you're forced to make it happen.


----------



## astyle (May 13, 2021)

Looks like this can go both ways... I've seen Perl and Ruby in Ports as 'having Qt bindings'. But it looks like both Perl and Ruby are actually written in C to begin with, and so is Python... Things you learn while watching ports compile!


----------



## zirias@ (May 13, 2021)

Menelkir said:


> Let me guess, maintaining bindings for those things is overcomplicated because they have 80% of things that the main developer thought that could be "used later" but in practice will never be used, but is so tangled inside that you're forced to make it happen.


Not exactly. I guess my main problem was this typical "engineering" mindset to create an abstraction for everything, and by chosing win32 and Qt as backends, this became an impossible task very quickly  While win32 is as "bare-bones" as you can imagine (and full of weird stuff), Qt is pretty "high-level" abstract. What I _wanted_ to do is to create cross-platform GUI applications in C(!) easily. I think this would be perfectly possible, but, too much work for a single person


----------



## kpedersen (May 13, 2021)

Zirias said:


> It's manual work for sure. I'd love to see a "C binding" for Qt  Would be perfectly possible, but definitely a lot of work to maintain. I once tried (in a toy project) to define a simple GUI C API myself and had two backends for it, win32 and Qt. Well, it could display _something_ (a window, some buttons, labels, etc), but I abandoned it soon


Agreed, I am also fairly sure it would help the binding process to other languages in future too.
Nice. I have looked into doing similar in the past but it is just such a large amount of repetitive work. The worst thing is that it isn't particularly complex so that unfortunately doesn't keep us interested long enough to complete it either!

Perhaps if we can get ~50 developers together, each doing a tiny GUI component... it could get finished!


----------



## astyle (May 13, 2021)

Zirias said:


> Not exactly. I guess my main problem was this typical "engineering" mindset to create an abstraction for everything, and by chosing win32 and Qt as backends, this became an impossible task very quickly  While win32 is as "bare-bones" as you can imagine (and full of weird stuff), Qt is pretty "high-level" abstract. What I _wanted_ to do is to create cross-platform GUI applications in C(!) easily. I think this would be perfectly possible, but, too much work for a single person


I sometimes get lost in which way the abstraction needs to go. I can imagine C as being an abstraction over assembler, which in turn is an abstraction over simple commands like PUSH and ADD, which in turn are an abstraction over the logic gates like NAND and XOR.  But when I look at abstraction diagrams for GUI toolkits - I quickly get lost in figuring out what comes first, second, and so forth.


----------



## Alain De Vos (May 13, 2021)

Even wxwidgets is not simple. Virtual function tables, include files with macro expanding other macro's.


----------



## zirias@ (May 13, 2021)

kpedersen said:


> The worst thing is that it isn't particularly complex


You should probably scope the project to be "just" C bindings for Qt. With my approach (abstraction layer over Qt _and_ win32), it _was_ complex. And sure enough, I failed (probably for losing interest to do all that crap)

(edit: well, in my very personal view, the ONE weakness of Qt is that it's natively C++. This language _is_ ill-defined. GTK is pure C, but with GTK, I've seen a whole lot of problems, especially with portability to non-POSIX platforms. What I would absolutely *love* to see is something like Qt, but in plain good-old C)


----------



## Alain De Vos (May 21, 2021)

Program which draws a circle,


```
import cairo.Context:Context;
import gtk.Widget:Widget;
import gtk.DrawingArea:DrawingArea;
import gtk.Application: GtkApplication=Application;
import gtk.ApplicationWindow:Scoped,ApplicationWindow,GApplicationFlags;
import gio.Application: GioApplication=Application;


import std.stdio:writeln;
import std.process:executeShell;
import std.typecons:Tuple;
import std.array:split;
import std.algorithm.mutation:remove;
import std.string:replace;

class DA:DrawingArea {
public:
    this()
        { addOnDraw(&drawCallback);}
protected:
    bool drawCallback(Scoped!Context c,Widget w){
        c.setSourceRgba(0.5,0.5,0.5,0.5);
        c.setLineWidth(3);
        c.arc(125,125,25,0,6.28);
        c.stroke();
        return true;
    }
}

int main(string [] args){
    GtkApplication application;
    string title="org.MyApp";
    void activateClock(GioApplication app){
        ApplicationWindow win = new ApplicationWindow(application);
        win.setTitle(title);
        win.setDefaultSize( 250, 250 );
        auto da = new DA();
        win.add(da);
        da.show();
        win.showAll();
    }
    application = new GtkApplication(title, GApplicationFlags.FLAGS_NONE);
    application.addOnActivate(&activateClock);
    return application.run(args);
}
```


----------



## covacat (May 21, 2021)

here is my circle

```
clear;L=$(tput li);C=$(tput co);for i in $(jot 360);do res=$(echo "$C/2 + $L/3 *80/25*3/4* s($i*6.28/360);$L/2+ $L/3*c($i*6.28/360)"|bc -l);set -- $res;Y=${1%.*};X=${2%.*};tput cm $Y $X;echo "#";done
```
radius is a third of the terminal height; aspect ratio correction is assuming 80x25 fills a 4:3 screen


----------



## zirias@ (May 21, 2021)

Looks like an upcoming code-golfing challenge *scnr*


----------



## kpedersen (May 21, 2021)

Zirias said:


> Looks like an upcoming code-golfing challenge *scnr*


Heh, this is where someone with their own bespoke golfing language walks in:


```
..1#.6..;.1
```

Not that I could really verify that of course


----------



## astyle (May 21, 2021)

Alain De Vos said:


> Program which draws a circle,


This  dump truck of code is why I get lost. It takes that much just to draw a simple circle, let alone do anything like KTorrent, or kernel bug hunting. And even if it works (as in compiles with no complaints, runs without crashing, exits cleanly), there's still design diagrams after that (all that code needs to follow the logic specified in the design diagrams), and version control. For me, that does get to be a bit too much, even with the divide-and-conquer strategy. 

To top it all off, there's lexical parsers that supposedly find bugs and security holes that still require verification and re-compiling - If you enjoy that kind of enchilada, then it's your cup of tea.


----------



## Beastie7 (May 21, 2021)

Zirias said:


> I've seen a whole lot of problems, especially with portability to non-POSIX platforms



Would you mind going over some of them? I'm just starting to dig into the GTK world (GNOME is growing on me), and I'm quite fond of it all being in C. At least it's something your average kernel developer can creep into. Cairo is in C as well.


----------



## zirias@ (May 21, 2021)

Beastie7 said:


> Would you mind going over some of them? I'm just starting to dig into the GTK world (GNOME is growing on me), and I'm quite fond of it all being in C. At least it's something your average kernel developer can creep into. Cairo is in C as well.


I'd ask upstream devs of emulators/vice about it  Didn't use GTK myself. But I remember they ran into problems like a file dialog getting stuck on windows because it found a "drive letter" that wasn't accessible. Or some threading scheme not working correctly on windows that worked quite fine on POSIX platforms. I really don't remember all the details  

Qt has a slight advantage here because it abstracts more than _just_ the GUI.


----------



## Alain De Vos (May 21, 2021)

35 years ago I programmed "sprites" on a C-64. Peek and poke. And to warm reboot "sys 64738"
There are quit some games you can play on the emulator.


----------



## zirias@ (May 21, 2021)

Alain De Vos said:


> 35 years ago I programmed "sprites" on a C-64.


I still do  




_View: https://www.youtube.com/watch?v=EaeMbr6TuXQ_








						The Invitro by ExCeSs & Abyss Connection
					

Commodore 64 Invitation: The Invitro by ExCeSs & Abyss Connection by Abyss Connection and Excess. Released on 1 September 2019




					csdb.dk
				



(this features a "sprite multiplexer" cause the hardware only allows 8 sprites, but I needed more for the scrolltext)

(edit: graphics by "Almighty God" [aka Domingo], an awesome pixel artist from Spain. Everything else [code, music] by me)


----------



## kpedersen (May 21, 2021)

Beastie7 said:


> Would you mind going over some of them? I'm just starting to dig into the GTK world (GNOME is growing on me), and I'm quite fond of it all being in C. At least it's something your average kernel developer can creep into. Cairo is in C as well.


At work we have a fairly substantial port of Gtk2 which sits on top of SDL1 and SDL2 (Most of the work is actually inside GDK). We haven't even had to gut too much. So it can be very portable.

However by default (and especially the later versions), upstream Gtk is awkward to compile up on Windows. For a long time they even dropped support for the MSVC compiler. Obviously that compiler is fairly underwhelming, unfortunately so many Win32 middleware developers have tied themselves down to it and thus it is generally important to support for GtkWin32.

Things are getting better however. Check out: https://www.collabora.com/news-and-...nd-run-gtk-4-applications-with-visual-studio/

(I am actually a big fan of our internal Gtk2/SDL. It is very portable now and completely cut off from the mad direction and mess that Gnome is going. Gtk2 theme engines are also vastly superior than that CSS nonsense. If I have time, I might see if I can push to get it opened).


----------



## zirias@ (May 21, 2021)

kpedersen said:


> For a long time they even dropped support for the MSVC compiler. Obviously that compiler is fairly underwhelming, unfortunately so many Win32 middleware developers have tied themselves down to it and thus it is generally important to support for GtkWin32.


As an opensource dev, I'd just ignore that, for my own sanity. I remember I had a complete build system for MSVC/VisualStudio available in the first opensource tool of some reasonable size I released, "mkd64". I really lost any interest maintaining it. One of the reasons is that MS doesn't move at all regarding C. It looks like they consider C "obsolete" and C++ the "successor". And, frankly, this is bullshit.

It's of course all different if you do development in an enterprise context. But for me, releasing my C stuff as opensource, I just say: grab MSYS2 to build it yourself on Windows if you want. And if you don't want, that's not my problem.

So, I kind of understand where the GTK guys come from


----------



## Jose (May 21, 2021)

kpedersen said:


> (I am actually a big fan of our internal Gtk2/SDL. It is very portable now and completely cut off from the mad direction and mess that Gnome is going. Gtk2 theme engines are also vastly superior than that CSS nonsense. If I have time, I might see if I can push to get it opened).


That would be a game changer.


----------



## zirias@ (May 21, 2021)

Hm, reading that quote again: I don't think CSS is "nonsense", but applying it outside the web is questionable  As is stuff like "electron". Had to be said…


----------



## kpedersen (May 21, 2021)

Zirias said:


> So, I kind of understand where the GTK guys come from


Absolutely but then you get some CUDA, SteamVR or FBX SDK from a vendor that only provides a MSVC .lib and you start having to faff quite a bit.

Not an absolute blocker, (I like faffing ). However if you then are trying to integrate *your* middleware as a downstream product, then (even) further downstream then wants MSVC again and their build system is not geared up for mingw64.

Of course, C isn't a problem. This is only C++ and a lack of ABI stability.


----------



## zirias@ (May 21, 2021)

Isn't that a "critical mass" kind of thing? If all opensource C projects would stop supporting this horrible MSVC ecosystem, vendors would have to move


----------



## kpedersen (May 21, 2021)

Zirias said:


> Isn't that a "critical mass" kind of thing? If all opensource C projects would stop supporting this horrible MSVC ecosystem, vendors would have to move


Yeah its a good point. I wish open-source communities would "weaponize" a little more and become a little more opinionated in these kinds of matters rather than compromising too easily.

But ~2005, Microsoft pushed students into believing that the only solution for games was Windows, DirectX, Visual Studio. And we are still trying to undo that ancient damage. This kind of backwards thinking still lingers in the multimedia industry annoyingly. Only now do students no longer riot when told they will be taught OpenGL this semester 

Edit: As for CSS. Yeah, CSS for markup is good adequate. However I tend to believe we can do a bit better with proper compiled languages in a native environment that can interact with the underlying system.
But, I could be wrong, GUI building is arguably worse today than it was when VB6 was around XD


----------



## zirias@ (May 21, 2021)

kpedersen said:


> But, I could be wrong, GUI building is arguably worse today than it was when VB6 was around XD


I _assume_ I know what you mean. All this "declarative" stuff for native GUIs IMHO is heading into the wrong direction. A local GUI just isn't "web". I can just speak for myself: I prefer Qt for native GUI, but when I use it, I never use their "designer" or their specialized file format for GUI description. I just define the GUI programmatically, by creating a nice tree of objects 

(edit: and this is really only the GUI frontend, all my "business logic" typically resides in a C(!) library)


----------



## Alain De Vos (May 21, 2021)

I avoid also designers.
It makes you create objects wich are not part of your code.


----------



## astyle (May 21, 2021)

Alain De Vos said:


> I avoid also designers.


Yeah, but it can get tedious to do the if-elses... Case 1, you call lib1, case 2, you call lib2, case 3, you call lib3... default, call libX.  Those things do grow out of control, even with programming assists like code folding. 

Or, trying to create a table for displaying different things. Depending on the toolkit you use, it can be a pain just to find the correct place in the code! and balancing the brackets/parentheses correctly is only part of the equation.


----------



## kpedersen (May 21, 2021)

Yeah, a designer might be fun to use but think of your poor maintainer 10 years down the line who can no longer get the original designer program compiling and now has to go through all that generated cruft manually to update a button.

Though I do find the current approach of hbox, vbox, hbox, vbox a little tedious to code. And yet when it comes down to it, this row column / table approach to layout still seems the best in terms of resizing.


----------



## astyle (May 21, 2021)

kpedersen said:


> Yeah, a designer might be fun to use but think of your poor maintainer 10 years down the line who can no longer get the original designer program compiling and now has to go through all that generated cruft manually to update a button.
> 
> Though I do find the current approach of hbox, vbox, hbox, vbox a little tedious to code. And yet when it comes down to it, this row column / table approach to layout still seems the best in terms of resizing.


10 years down the road, not only the codebase will be different, but it's gonna be a whole different ballgame. Has anyone done a diff on kernel code to load a device driver into memory? What a difference 10 years will make. 10 years ago, 4 GB of RAM was sufficient for newer PC's - nowadays, 16 GB is the norm. Makes you wonder how the Linux kernel was able to run in just 32MB of RAM.


----------



## ct85711 (May 21, 2021)

Even now, the kernel barely uses much memory; as I know Linux will gladly run on 2G of ram perfectly fine.  The part that has been making the memory demand exploding up significantly is more of Firefox/Chrome, and the GUI.  It is sad how much memory the web browser takes, just to make it look "pretty".


----------



## Zvoni (Jul 8, 2021)

Yeah, late to the party (as always ), but i'm going to throw FreePascal/Lazarus in here.
Write once, compile anywhere
Choose WidgetSet (and yes, QT is supported), choose target-platform, hit compile (if you have the cross-compiler installed), have fun.

No test for FreeBSD, but i did write a small program on a Linux-Dev-Machine, moved the source-code onto a Windows-Machine, compiled there, it ran, moved the source-code to a Mac, compiled there, it ran (with one exception because of a very specific component).

The easiest way to install is to use fpcupdeluxe which itself is written in FreePascal/Lazarus
Nota bene: any dependencies have to be installed beforehand (QT, GTK, my dirty socks, whatever)


----------



## Alain De Vos (Jul 8, 2021)

Pascal is a good language to program with.


----------



## astyle (Jul 8, 2021)

Even if you use a so-called 'cross-compiler',  there are still limitations. If the 'cross compiler' lives on FreeBSD, there's very little chance that the resulting binary will run on Windows. Even with Java trying to enter the conversation as a counter-example, you still need to find a JVM to install on Windows first, and make sure the versions match, and this needs to happen before you copy the compiled binary from one system to another. 

Even when moving source code from one system to another (From FreeBSD to Windows), you have to make sure that on both systems, a usable compiler is installed beforehand.

HTML5 is pretty nice that way, but it's limited to displaying info, no serious computation like 'Show me 1 + 1' to spit out 2.


----------



## kpedersen (Jul 8, 2021)

astyle said:


> Even if you use a so-called 'cross-compiler',  there are still limitations. If the 'cross compiler' lives on FreeBSD, there's very little chance that the resulting binary will run on Windows.


It would be a fairly rubbish cross compiler if this was the case.
If you have wine installed, you should have *wineg++*. This is a fairly good gcc / mingw-w64 based cross compiler. There is an older win32 one here too devel/mingw32-gcc.

The clang in base can also output to WebAssembly and Android. Considering that we also have a decent Linux compat layer, FreeBSD actually makes a fantastic build server platform. It can pretty much compile to all common platforms except for locked down macOS (which needs other crap like DRM signatures, provisioning profiles, etc).


----------



## Vull (Jul 9, 2021)

I worked off and on as a freelancer, jobber, or full-time staff programmer, from 1981 to 2009, mostly using various platform-dependent flavors of BASIC, Assembler, Pascal, and C++, in approximately that order. I attempted unsuccessfully to break platform-dependency using web-based Java applets in the late 80s & early 90s, but eventually abandoned that effort, and from the mid-90s through the early 21st century started leaning more and more towards web-based applications, mainly using PHP-generated HTML in conjunction with CSS, ECMAScript (javascript), and SQL, initially using MySQL, but eventually switching completely over to PostgreSQL, after supporting both for about 2-3 years. Throughout all this time I've done a lot of shell scripting, mostly with ksh and sh, but also dabbling a bit in old-school JCL, and more than a few MS-DOS style "batch" files.

A lot of this thread reads like Greek to me, once again confirming the widely-held notion that any programmer needs to learn new skilllsets every 3 to 5 years just to keep up.


----------



## Zvoni (Jul 9, 2021)

astyle said:


> Even if you use a so-called 'cross-compiler',  there are still limitations. If the 'cross compiler' lives on FreeBSD, there's very little chance that the resulting binary will run on Windows. Even with Java trying to enter the conversation as a counter-example, you still need to find a JVM to install on Windows first, and make sure the versions match, and this needs to happen before you copy the compiled binary from one system to another.
> 
> Even when moving source code from one system to another (From FreeBSD to Windows), you have to make sure that on both systems, a usable compiler is installed beforehand.
> 
> HTML5 is pretty nice that way, but it's limited to displaying info, no serious computation like 'Show me 1 + 1' to spit out 2.


I think you misunderstood: The crosscompiler of FreePascal creates native target-binaries






						Cross compiling - Lazarus wiki
					






					wiki.lazarus.freepascal.org
				




No VM needed

And FreePascal/Lazarus comes with native compiler(s) for each ( ! ) Dev-Platform
Reason: The compiler is self-hosted (a.k.a. the compiler itself is written in Freepascal)


----------



## astyle (Jul 9, 2021)

Zvoni said:


> I think you misunderstood: The crosscompiler of FreePascal creates native target-binaries
> 
> 
> 
> ...


Even with that, you still need a version of FreePascal for FreeBSD, and a copy for Windows, and make sure the versions match. You can copy source code and set target flags... it would be interesting to see the results of using FreePascal  to compile a native Windows .exe binary: Will it make a difference if compiled on FreeBSD with proper flags set versus compiling the unmodified source with default settings on Windows? To properly answer a question like that, you gotta set up a tightly controlled experiment with a null hypothesis.


----------



## Alain De Vos (Jul 9, 2021)

You can make a dlang-gtkd-gui application on freebsd/linux/windows without the need to change any line of code except for the building process.


----------



## Jose (Jul 9, 2021)

Zvoni said:


> I think you misunderstood: The crosscompiler of FreePascal creates native target-binaries


Every cross-compiler does that. It's the very definition of cross compilation.





						Cross-Compilation (automake)
					

Cross-Compilation (automake)



					www.gnu.org


----------



## Deleted member 30996 (Jul 10, 2021)

My CSS circle:


```
#circle {
background: #000000;
border-radius: 50%;
width: 100px;
height: 100px;
}
```


----------



## Crivens (Jul 12, 2021)

I am currently using FreePascal for a FreeBSD/Linux/Windows app. I will see how that works out.
Writing software in FPC is different. You find that the language forces better design on you. The last Win/Linux tool I did (on the job) is horrible, in C#.


----------



## Alain De Vos (Jul 12, 2021)

Give dlang-gtkd is a try. If you don't need external libraries except sql this works nice.


----------



## eternal_noob (Aug 12, 2021)

I am a fan of OpenGL and i wanted a nice GUI library for it. So i had to try Dear ImGui with its OpenGL backend lately. I must say that it does its job nicely.


----------

