Linux: Add AppMenu in GNOME Shell bar

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Linux: Add AppMenu in GNOME Shell bar

Post by fsw »

Since GNOME 3.10 the GNOME Shell finally seems to be usable to the point to be an enjoyable and productive desktop environment.

GNOME has introduced the AppMenu for some of its core applications starting with GNOME 3.4. This means that part of the menu or the whole menu is displayed as a drop-down on the top GNOME Shell bar.

Some applications now have two menus: an AppMenu that's displayed on the top GNOME Shell bar which is used for actions that affect the entire application and another menu that's displayed in the application window, which affects the currently focused window.

Some GNOME applications only use an AppMenu, without a secondary window menu.

Here a simple c program that shows the AppMenu (without menu separators) that shows how it looks like:

Code: Select all

#include <gtk/gtk.h>

static void preferences (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	g_print ("This does nothing. It is only a demonstration.\n");
}

static void help (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	g_print ("This does nothing. It is only a demonstration.\n");
}

static void about (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	g_print ("This does nothing. It is only a demonstration.\n");
}

static void quit (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	GApplication *application = user_data;
	g_application_quit (application);
}

static void startup (GtkApplication *application, gpointer user_data)
{
  static const GActionEntry actions[] = {
    { "preferences", preferences },
    { "help", help },
    { "about", about },
    { "quit", quit }
  };

  GMenu *menu;

  g_action_map_add_action_entries (G_ACTION_MAP (application), actions, G_N_ELEMENTS (actions), application);

  menu = g_menu_new ();
  g_menu_append (menu, "Preferences", "app.preferences");
  g_menu_append (menu, "Help",  "app.help");
  g_menu_append (menu, "About", "app.about");
  g_menu_append (menu, "Quit",  "app.quit");
  gtk_application_set_app_menu (application, G_MENU_MODEL (menu));
  g_object_unref (menu);
}

static void activate (GtkApplication *app, gpointer user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);

  gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (app));
  gtk_window_set_title (GTK_WINDOW (window), "Hello GNOME");

  gtk_widget_show_all (GTK_WIDGET (window));
}

int main (int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example",G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "startup",  
                    G_CALLBACK (startup), NULL);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return status;
}
The window menu is not in a menu bar but is activated with a menu button:

Code: Select all

#include <gtk/gtk.h>

/* Callback function for the undo action */
static void item2_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
  g_print ("You clicked \"Item 2\"\n");
}

static void activate (GtkApplication *app, gpointer user_data)
{
  GMenu         *submenu;
  GtkWidget     *grid;
  GMenu         *menumodel;
  GtkWidget     *window;
  GtkWidget     *menubutton;
  GSimpleAction *item2_action;

  window = gtk_application_window_new (app);
  grid = gtk_grid_new ();

  gtk_window_set_title (GTK_WINDOW (window), "MenuButton Example");
  gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);

  menubutton = gtk_menu_button_new ();
  gtk_widget_set_size_request (menubutton, 80, 35);

  gtk_grid_attach (GTK_GRID (grid), menubutton, 0, 0, 1, 1);
  gtk_container_add (GTK_CONTAINER (window), grid);

  menumodel = g_menu_new ();
  g_menu_append (menumodel, "Item 1", "app.item1");
  g_menu_append (menumodel, "Item 2", "win.item2");

  submenu = g_menu_new ();
  g_menu_append_submenu (menumodel, "Other", G_MENU_MODEL (submenu));
  g_menu_append (submenu, "Quit", "app.quit");
  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menubutton), G_MENU_MODEL (menumodel));

  item2_action = g_simple_action_new ("item2", NULL);
  g_signal_connect (item2_action, "activate", G_CALLBACK (item2_callback), GTK_WINDOW (window));
  g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (item2_action));

  gtk_widget_show_all (window);
}


static void item1_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
  g_print ("You clicked \"Item 1\"\n");
}

static void quit_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
  GApplication *application = user_data;
  g_application_quit (application);
}

static void startup (GApplication *app, gpointer user_data)
{
  GSimpleAction *item1_action;
  GSimpleAction *quit_action;

  item1_action = g_simple_action_new ("item1", NULL);
  g_signal_connect (item1_action, "activate", G_CALLBACK (item1_callback), app);
  g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (item1_action));

  quit_action = g_simple_action_new ("quit", NULL);
  g_signal_connect (quit_action, "activate", G_CALLBACK (quit_callback), app);
  g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (quit_action));
}


int main (int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return status;
}

I am to provide the public with beneficial shocks.
Alfred Hitshock
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Linux: Add AppMenu in GNOME Shell bar

Post by uwekel »

This is interresting! Did you already do an adaption into PureBasic?
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Linux: Add AppMenu in GNOME Shell bar

Post by fsw »

I think it's not doable without Fred's help.

This is because:

Code: Select all

gtk_application_set_app_menu(*Application, menu)
needs *Application, which is buried inside Fred's code.

And it's needed in order to attach the menu to the application.
(as it's not attached to the window...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Linux: Add AppMenu in GNOME Shell bar

Post by uwekel »

Why not create a dummy application with

Code: Select all

gtk_application_new
?
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Linux: Add AppMenu in GNOME Shell bar

Post by fsw »

Don't think it's that simple.
PureBasic has now a gtk3 subsystem but it's still a stepchild.
PureBasic is still using gtk stuff that is deprecated.
Example: still using GtkAction instead of GSimpleAction etc.
Which is fine for gtk2 but in order to use gtk3 to the full more work needs to be done...
...from the inside out. :mrgreen:

I am to provide the public with beneficial shocks.
Alfred Hitshock
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Linux: Add AppMenu in GNOME Shell bar

Post by uwekel »

Yes, that's a shame. I think the primay focus of PB is Windows, then Mac and Linux at last so a lot of stuff is just pending or not well implemented (e.g. like SpinGadget). More and more i tend to program in Python, which has very good GTK bindings. But i also love PB :?
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Linux: Add AppMenu in GNOME Shell bar

Post by uwekel »

Ok, it took a while, but now i have found a solution :-)

Code: Select all

ImportC "-lgtk-3"
  gtk_application_new(Id.p-utf8, Flags=0)
  gtk_application_window_new(*application)
  gtk_application_add_window(*application, *window)
  gtk_application_set_app_menu(*application, *app_menu)
  gtk_application_set_menubar(*application, *menubar)
  gtk_builder_new()
  gtk_builder_add_from_string(*builder, buffer.p-utf8, length=-1, *error=0)
  gtk_builder_get_object(*builder, name.p-utf8)
  gtk_widget_show_all(*Wigdet)
  gtk_window_set_title(*Window, Title.p-utf8)
  gtk_window_set_default_size(*Window, Width.l, Height.l)
  gtk_window_set_position(*Window, Position.l)
EndImport
ImportC "-lgobject-2.0"
  g_signal_connect_data(*Instance, Signal.p-utf8, *Handler, *Data=0, Flags.l=0)
EndImport
ImportC "-lgio-2.0"
  g_action_map_add_action(*application, *action)
  g_application_run(*application, argc=0, *argv=0)
  g_application_quit(*application)
  g_simple_action_new(name.p-utf8, parameter_type=0)
EndImport

Global *app, *win

ProcedureC PreferencesActivated()
  Debug "PreferencesActivated"
EndProcedure
ProcedureC QuitActivated()
  Debug "QuitActivated"
  g_application_quit(*app)
EndProcedure
ProcedureC Startup(*app)
  Debug("Startup")
  
  *win = gtk_application_window_new(*app)
  gtk_window_set_default_size(*win, 275, 275)
  gtk_window_set_position(*win, #GTK_WIN_POS_CENTER)
  gtk_window_set_title(*win, "GTK3-Test")
  gtk_application_add_window(*app, *win)
  
  s.s = "<?xml version='1.0'?>" +
  "<interface>" +
  "<menu id='appmenu'>" +
  "  <section>" +
  "  <item>" +
  "    <attribute name='label' translatable='yes'>Einstellungen</attribute>" +
  "    <attribute name='action'>app.preferences</attribute>" +
  "  </item>" +
  "  </section>" +
  "  <section>" +
  "  <item>" +
  "    <attribute name='label' translatable='yes'>Beenden</attribute>" +
  "    <attribute name='action'>app.quit</attribute>" +
  "    <attribute name='accel'><Primary>q</attribute>" +
  "  </item>" +
  "  </section>" +
  "</menu>" +
  "</interface>"
  
  *builder = gtk_builder_new()
  gtk_builder_add_from_string(*builder, s)
  *appmenu = gtk_builder_get_object(*builder, "appmenu")
  gtk_application_set_app_menu(*app, *appmenu)
  
  ;*menubar = gtk_builder_get_object(*builder, "menubar")
  ;gtk_application_set_menubar(*app, *menubar)
  
  *actpref = g_simple_action_new("preferences")
  g_signal_connect_data(*actpref, "activate", @PreferencesActivated())
  g_action_map_add_action(*app, *actpref)

  *actquit = g_simple_action_new("quit")
  g_signal_connect_data(*actquit, "activate", @QuitActivated())
  g_action_map_add_action(*app, *actquit)
  
EndProcedure
ProcedureC Activate(*app)
  Debug("Activate")
  gtk_widget_show_all(*win)
EndProcedure
ProcedureC Shutdown(*app)
  Debug("Shutdown")
EndProcedure
Procedure Main()
  *app = gtk_application_new("purebasic.gnome")
  g_signal_connect_data(*app, "startup", @Startup())
  g_signal_connect_data(*app, "activate", @Activate())
  g_signal_connect_data(*app, "shutdown", @Shutdown()) 
  g_application_run(*app)
EndProcedure

Main()
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
User avatar
bembulak
Enthusiast
Enthusiast
Posts: 572
Joined: Mon Mar 06, 2006 3:53 pm
Location: Austria

Re: Linux: Add AppMenu in GNOME Shell bar

Post by bembulak »

Wow! That's interesting. Thank you for sharing. However I must say, that looks quite complicated to me.
cheers,

bembulak
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Linux: Add AppMenu in GNOME Shell bar

Post by fsw »

Just saw this. 8)
Will test it out as soon as I can.
(although I'm little upset with Gnome 3 as it always makes me install a full sh*t load of Gnome apps I don't want.)

On the other hand (AFAIK) Gnome 3 is the only GTK3 based Desktop that will play nice with Wayland in the future...
(or I should take another look at the Budgie-Desktop...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
bembulak
Enthusiast
Enthusiast
Posts: 572
Joined: Mon Mar 06, 2006 3:53 pm
Location: Austria

Re: Linux: Add AppMenu in GNOME Shell bar

Post by bembulak »

Budgie looks interesting, yes!
cheers,

bembulak
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Linux: Add AppMenu in GNOME Shell bar

Post by uwekel »

fsw wrote:...although I'm little upset with Gnome 3 as it always makes me install a full sh*t load of Gnome apps I don't want...
I did a script to get rid of some pakets:

Code: Select all

yum -y erase orca libreoffice*
And to install Purebasic dependancies as well:

Code: Select all

yum -y install gcc libstdc++-devel libstdc++-static gtk2-devel libgnome-devel libgnomeprintui22 libgnomeprintui22-devel SDL-devel xine-lib-devel unixODBC unixODBC-devel
So the system is setup in a couple of seconds :)
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
Post Reply