to build a clean GTK4 version of my program (https://atomes.ipcms.fr) I need to be able to add pango markup in GTK4 menus, and, the menu(s) must be C coded and not read from XML file(s).
This question follows the one from this post (that contains a visual illustration):
A little bit more than a year ago I asked the same thing, got answers, waited for a long time for updates in the GTK4 lib, hopping for the answer to work at some point … and no … or maybe it does and I am doing something wrong …
Basically it works when reading the menu from a XML file, and it does not when coding directly the menu elements, and I really, really, must do it this way.
Here is a piece of example code I wrote:
#include <gtk/gtk.h>
GtkApplication * TestApp = NULL;
void menu_bar_action (GSimpleAction * action, GVariant * parameter, gpointer data)
{
gchar * name = g_strdup_printf ("%s", g_action_get_name(G_ACTION(action)));
if (g_strcmp0 (name, "quit") == 0)
{
g_application_quit (G_APPLICATION(TestApp));
}
}
GMenuItem * create_gmenu_item (const gchar * label, const gchar * action)
{
GMenuItem * item;
item = g_menu_item_new (label, action);
// Requesting to use markup here:
g_menu_item_set_attribute (item, "use-markup", "b", TRUE, NULL);
return item;
}
void append_menu_item (GMenu * menu, const gchar * label, const gchar * action)
{
GMenuItem * item = create_gmenu_item (label, action);
g_menu_append_item (menu, item);
g_object_unref (item);
}
void run_program (GApplication * app, gpointer data)
{
GtkWidget * window = gtk_application_window_new (GTK_APPLICATION(app));
gtk_window_set_title (GTK_WINDOW(window), "Test");
gtk_window_set_resizable (GTK_WINDOW(window), TRUE);
gtk_widget_set_size_request (window, 900, 450);
#ifdef UIMODE
GtkBuilder * builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "test.ui", NULL);
gtk_application_set_menubar (GTK_APPLICATION (app),
G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
g_object_unref (builder);
#else
GMenu * menubar = g_menu_new();
GMenu * menu = g_menu_new ();
// Trying different things just in case:
append_menu_item (menu, "C(H)<sub>2</sub>", "None");
append_menu_item (menu, "C(H)<sub>3</sub>", "None");
append_menu_item (menu, "C(H)<sub>4</sub>", "None");
append_menu_item (menu, "Quit", "app.quit");
g_menu_append_submenu (menubar, "File", G_MENU_MODEL (menu));
g_object_unref (menu);
gtk_application_set_menubar (GTK_APPLICATION(app), G_MENU_MODEL(menubar));
#endif
GSimpleAction * act = g_simple_action_new ("quit", NULL);
g_signal_connect (act, "activate", G_CALLBACK(menu_bar_action), NULL);
g_action_map_add_action (G_ACTION_MAP(GTK_APPLICATION(app)), G_ACTION(act));
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW(window), TRUE);
gtk_window_present (GTK_WINDOW(window));
}
int main (int argc, char *argv[])
{
// setlocale(LC_ALL,"en_US");
gtk_disable_setlocale ();
TestApp = gtk_application_new (g_strdup_printf ("test._%d.gtk", (int)clock()), G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (G_OBJECT(TestApp), "activate", G_CALLBACK(run_program), NULL);
int status = g_application_run (G_APPLICATION (TestApp), 0, NULL);
g_object_unref (TestApp);
return status;
}
And the ‘test.ui’ optional XML file for the menu:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menubar">
<submenu>
<attribute name="label" translatable="yes">Test</attribute>
<section>
<item>
<attribute name="label" translatable="yes">C(H)<sub>2</sub></attribute>
<attribute name="use-markup">TRUE</attribute>
<attribute name="action">None</attribute>
</item>
<item>
<attribute name="label" translatable="yes">C(H)<sub>3</sub></attribute>
<attribute name="use-markup">TRUE</attribute>
<attribute name="action">None</attribute>
</item>
<item>
<attribute name="label" translatable="yes">C(H)<sub>3</sub></attribute>
<attribute name="use-markup">TRUE</attribute>
<attribute name="action">None</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</submenu>
</menu>
</interface>
If I build the code using:
#!/bin/bash
app=$1
LIBS="-Wl,--export-dynamic `pkg-config --libs gtk4`"
INCLUDES="`pkg-config --cflags gtk4`"
CFLAGS="-O2"
gcc -o $app'.x' $CFLAGS $INCLUDES $app'.c' $LIBS -DUIMODE
Then the menu, loaded from the XML file properly uses pango markup.
However If I build the code using:
#!/bin/bash
app=$1
LIBS="-Wl,--export-dynamic `pkg-config --libs gtk4`"
INCLUDES="`pkg-config --cflags gtk4`"
CFLAGS="-O2"
gcc -o $app'.x' $CFLAGS $INCLUDES $app'.c' $LIBS
Then no markup.
I tested this on a clean, all new Debian 12, with GTK 4.8.3.
You will understand based on my examples that I want to display chemical formula.
Thanks in advance if you have any ideas to help !
Best regards