[gnome-panel] menu: implement main-menu applet



commit 85caa9e0e1eababc92ed09b710a665c085ee96be
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Sep 13 01:21:32 2018 +0300

    menu: implement main-menu applet
    
    This is not exactly same as original menu-button object, but
    hopefully close enough.
    
    Icon and arrow are now images (GtkImage) instead of pixbufs that
    are placed into GtkOverlay. This is biggest change!
    
    For those who dislike arrow there is setting to disable it, fixes
    old bug - https://bugzilla.gnome.org/show_bug.cgi?id=598196.

 data/theme/common.css                              |  16 +
 modules/menu/Makefile.am                           |  10 +
 modules/menu/gp-main-menu-applet.c                 | 536 ++++++++++++++++++++-
 modules/menu/gp-menu-button.c                      |  47 ++
 modules/menu/gp-menu-button.h                      |  32 ++
 modules/menu/gp-menu-module.c                      |   2 +-
 ....gnome.gnome-panel.applet.main-menu.gschema.xml |  26 +
 po/POTFILES.in                                     |   1 +
 8 files changed, 667 insertions(+), 3 deletions(-)
---
diff --git a/data/theme/common.css b/data/theme/common.css
index c170c4381..b1d4441cc 100644
--- a/data/theme/common.css
+++ b/data/theme/common.css
@@ -30,3 +30,19 @@ panel-toplevel.right gp-applet > menubar > .gp-image-menu-item > image:dir(rtl)
   margin-left: 0px;
   margin-top: 5px;
 }
+
+panel-toplevel.horizontal gp-menu-button {
+  padding: 0 2px;
+}
+
+panel-toplevel.vertical gp-menu-button {
+  padding: 2px 0;
+}
+
+panel-toplevel.horizontal gp-menu-button .icon {
+  padding: 0 4px;
+}
+
+panel-toplevel.vertical gp-menu-button .icon {
+  padding: 4px 0;
+}
diff --git a/modules/menu/Makefile.am b/modules/menu/Makefile.am
index 98d138497..159d22dd8 100644
--- a/modules/menu/Makefile.am
+++ b/modules/menu/Makefile.am
@@ -30,6 +30,8 @@ menu_la_SOURCES = \
        gp-menu-bar-applet.h \
        gp-menu-bar.c \
        gp-menu-bar.h \
+       gp-menu-button.c \
+       gp-menu-button.h \
        gp-menu-module.c \
        gp-menu-utils.c \
        gp-menu-utils.h \
@@ -60,6 +62,12 @@ menu_la_LDFLAGS = \
        $(AM_LDFLAGS) \
        $(NULL)
 
+gsettings_SCHEMAS = \
+       org.gnome.gnome-panel.applet.main-menu.gschema.xml \
+       $(NULL)
+
+@GSETTINGS_RULES@
+
 menu_resources := $(shell $(GLIB_COMPILE_RESOURCES) \
        --sourcedir=$(srcdir) --generate-dependencies \
        $(srcdir)/menu.gresource.xml)
@@ -117,10 +125,12 @@ EXTRA_DIST = \
        org.freedesktop.login1.Manager.xml \
        org.gnome.ScreenSaver.xml \
        org.gnome.SessionManager.xml \
+       $(gsettings_SCHEMAS) \
        $(menu_resources) \
        $(NULL)
 
 CLEANFILES = \
+       *.gschema.valid \
        $(BUILT_SOURCES) \
        $(NULL)
 
diff --git a/modules/menu/gp-main-menu-applet.c b/modules/menu/gp-main-menu-applet.c
index fb948b466..a82d82f12 100644
--- a/modules/menu/gp-main-menu-applet.c
+++ b/modules/menu/gp-main-menu-applet.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2003 Sun Microsystems, Inc.
  * Copyright (C) 2018 Alberts Muktupāvels
  *
  * This program is free software: you can redistribute it and/or modify
@@ -13,21 +14,43 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Alberts Muktupāvels <alberts muktupavels gmail com>
+ *     Mark McLoughlin <mark skynet ie>
  */
 
 #include "config.h"
 
 #include <glib/gi18n-lib.h>
 #include <libgnome-panel/gp-action.h>
+#include <libgnome-panel/gp-image-menu-item.h>
 
+#include "gp-lock-logout.h"
 #include "gp-main-menu-applet.h"
+#include "gp-menu-button.h"
 #include "gp-menu-utils.h"
+#include "gp-menu.h"
+#include "gp-places-menu.h"
+#include "gp-user-menu.h"
 
+#define MAIN_MENU_SCHEMA "org.gnome.gnome-panel.applet.main-menu"
 #define RESOURCE_PATH "/org/gnome/gnome-panel/modules/menu"
 
 struct _GpMainMenuApplet
 {
-  GpApplet parent;
+  GpApplet      parent;
+
+  GSettings    *settings;
+
+  GtkWidget    *button;
+  GtkWidget    *image;
+  GtkWidget    *arrow;
+
+  gboolean      custom_menu;
+
+  GtkWidget    *menu;
+  GpLockLogout *lock_logout;
 };
 
 static void gp_action_interface_init (GpActionInterface *iface);
@@ -35,11 +58,60 @@ static void gp_action_interface_init (GpActionInterface *iface);
 G_DEFINE_TYPE_WITH_CODE (GpMainMenuApplet, gp_main_menu_applet, GP_TYPE_APPLET,
                          G_IMPLEMENT_INTERFACE (GP_TYPE_ACTION, gp_action_interface_init))
 
+static void
+popup_menu (GpMainMenuApplet *main_menu,
+            GdkEvent         *event)
+{
+  GdkGravity widget_anchor;
+  GdkGravity menu_anchor;
+
+  switch (gp_applet_get_position (GP_APPLET (main_menu)))
+    {
+      case GTK_POS_TOP:
+        widget_anchor = GDK_GRAVITY_SOUTH_WEST;
+        menu_anchor = GDK_GRAVITY_NORTH_WEST;
+        break;
+
+      case GTK_POS_LEFT:
+        widget_anchor = GDK_GRAVITY_NORTH_EAST;
+        menu_anchor = GDK_GRAVITY_NORTH_WEST;
+        break;
+
+      case GTK_POS_RIGHT:
+        widget_anchor = GDK_GRAVITY_NORTH_WEST;
+        menu_anchor = GDK_GRAVITY_NORTH_EAST;
+        break;
+
+      case GTK_POS_BOTTOM:
+        widget_anchor = GDK_GRAVITY_NORTH_WEST;
+        menu_anchor = GDK_GRAVITY_SOUTH_WEST;
+        break;
+
+      default:
+        g_assert_not_reached ();
+        break;
+    }
+
+  gtk_menu_popup_at_widget (GTK_MENU (main_menu->menu),
+                            main_menu->button,
+                            widget_anchor, menu_anchor,
+                            event);
+}
+
 static gboolean
 gp_main_menu_applet_main_menu (GpAction *action,
                                guint32   time)
 {
-  return FALSE;
+  GpMainMenuApplet *main_menu;
+
+  main_menu = GP_MAIN_MENU_APPLET (action);
+
+  if (main_menu->menu == NULL)
+    return FALSE;
+
+  popup_menu (main_menu, NULL);
+
+  return TRUE;
 }
 
 static void
@@ -48,6 +120,338 @@ gp_action_interface_init (GpActionInterface *iface)
   iface->main_menu = gp_main_menu_applet_main_menu;
 }
 
+static void
+update_arrow (GpMainMenuApplet *main_menu,
+              GtkPositionType   position)
+{
+  const gchar *icon_name;
+  GtkAlign halign;
+  GtkAlign valign;
+
+  switch (position)
+    {
+      case GTK_POS_LEFT:
+        icon_name = "go-next-symbolic";
+        halign = GTK_ALIGN_END;
+        valign = GTK_ALIGN_START;
+        break;
+
+      case GTK_POS_RIGHT:
+        icon_name = "go-previous-symbolic";
+        halign = GTK_ALIGN_START;
+        valign = GTK_ALIGN_START;
+        break;
+
+      case GTK_POS_BOTTOM:
+        icon_name = "go-up-symbolic";
+        halign = GTK_ALIGN_END;
+        valign = GTK_ALIGN_START;
+        break;
+
+      case GTK_POS_TOP:
+      default:
+        icon_name = "go-down-symbolic";
+        halign = GTK_ALIGN_START;
+        valign = GTK_ALIGN_END;
+        break;
+    }
+
+  gtk_image_set_from_icon_name (GTK_IMAGE (main_menu->arrow), icon_name,
+                                GTK_ICON_SIZE_MENU);
+
+  gtk_widget_set_halign (main_menu->arrow, halign);
+  gtk_widget_set_valign (main_menu->arrow, valign);
+}
+
+static void
+update_icon (GpMainMenuApplet *main_menu)
+{
+  GIcon *icon;
+  gchar *custom_icon;
+  GtkPositionType position;
+
+  icon = NULL;
+  custom_icon = g_settings_get_string (main_menu->settings, "custom-icon");
+
+  if (*custom_icon != '\0')
+    icon = g_themed_icon_new (custom_icon);
+
+  if (icon == NULL &&
+      main_menu->menu != NULL &&
+      main_menu->custom_menu)
+    icon = gp_menu_get_icon (GP_MENU (main_menu->menu));
+
+  if (icon == NULL)
+    icon = g_themed_icon_new ("start-here");
+
+  gtk_image_set_from_gicon (GTK_IMAGE (main_menu->image), icon,
+                            GTK_ICON_SIZE_MENU);
+
+  g_object_unref (icon);
+  g_free (custom_icon);
+
+  position = gp_applet_get_position (GP_APPLET (main_menu));
+  update_arrow (main_menu, position);
+}
+
+static gchar *
+split_menu_uri (const gchar  *menu_uri,
+                gchar       **menu_scheme)
+{
+  gchar *p;
+
+  if (*menu_uri == '\0')
+    return NULL;
+
+  p = strchr (menu_uri, ':');
+
+  if (!p || p == menu_uri)
+    return NULL;
+
+  g_assert (menu_scheme != NULL);
+  *menu_scheme = g_strndup (menu_uri, p - menu_uri);
+
+  if (*(++p) != '/')
+    {
+      g_free (*menu_scheme);
+      *menu_scheme = NULL;
+      return NULL;
+    }
+
+  /* skip extra leading slashes */
+  while (*p != '\0' && *(p + 1) == '/')
+    p++;
+
+  return g_strdup (p);
+}
+
+static gchar *
+get_applications_menu (void)
+{
+  const gchar *xdg_menu_prefx;
+
+  xdg_menu_prefx = g_getenv ("XDG_MENU_PREFIX");
+  if (!xdg_menu_prefx || *xdg_menu_prefx == '\0')
+    return g_strdup ("gnome-applications.menu");
+
+  return g_strdup_printf ("%sapplications.menu", xdg_menu_prefx);
+}
+
+static void
+menu_icon_size_cb (GpApplet   *applet,
+                   GParamSpec *pspec,
+                   GtkImage   *image)
+{
+  guint icon_size;
+
+  icon_size = gp_applet_get_menu_icon_size (applet);
+  gtk_image_set_pixel_size (image, icon_size);
+}
+
+static void
+append_places_item (GpMainMenuApplet *main_menu,
+                    GtkMenu          *menu)
+{
+  guint icon_size;
+  GtkWidget *icon;
+  GtkWidget *item;
+  GtkWidget *places_menu;
+
+  icon_size = gp_applet_get_menu_icon_size (GP_APPLET (main_menu));
+  icon = gtk_image_new_from_icon_name ("folder", GTK_ICON_SIZE_MENU);
+  gtk_image_set_pixel_size (GTK_IMAGE (icon), icon_size);
+
+  g_signal_connect_object (main_menu, "notify::menu-icon-size",
+                           G_CALLBACK (menu_icon_size_cb), icon, 0);
+
+  item = gp_image_menu_item_new_with_label (_("Places"));
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+  gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), icon);
+  gtk_widget_show (item);
+
+  places_menu = gp_places_menu_new (GP_APPLET (main_menu));
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), places_menu);
+}
+
+static void
+append_user_item (GpMainMenuApplet *main_menu,
+                  GtkMenu          *menu)
+{
+  guint icon_size;
+  GtkWidget *icon;
+  gchar *user_name;
+  GtkWidget *item;
+  GtkWidget *user_menu;
+
+  icon_size = gp_applet_get_menu_icon_size (GP_APPLET (main_menu));
+  icon = gtk_image_new_from_icon_name ("computer", GTK_ICON_SIZE_MENU);
+  gtk_image_set_pixel_size (GTK_IMAGE (icon), icon_size);
+
+  g_signal_connect_object (main_menu, "notify::menu-icon-size",
+                           G_CALLBACK (menu_icon_size_cb), icon, 0);
+
+  user_name = gp_menu_utils_get_user_name ();
+  item = gp_image_menu_item_new_with_label (user_name);
+  g_free (user_name);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+  gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), icon);
+  gtk_widget_show (item);
+
+  user_menu = gp_user_menu_new (GP_APPLET (main_menu));
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), user_menu);
+
+  g_object_bind_property (user_menu, "empty", item, "visible",
+                          G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE |
+                          G_BINDING_INVERT_BOOLEAN);
+}
+
+static void
+append_menu_items_cb (GtkMenu          *menu,
+                      GpMainMenuApplet *main_menu)
+{
+  append_separator_if_needed (menu);
+  append_places_item (main_menu, menu);
+  append_user_item (main_menu, menu);
+
+  gp_lock_logout_append_to_menu (main_menu->lock_logout, menu);
+}
+
+static gboolean
+validate_scheme (const gchar  *scheme,
+                 gchar       **menu_file)
+{
+  if (g_strcmp0 (scheme, "applications") == 0)
+    {
+      *menu_file = get_applications_menu ();
+      return TRUE;
+    }
+  else if (g_strcmp0 (scheme, "gnomecc") == 0)
+    {
+      *menu_file = g_strdup ("gnomecc.menu");
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+update_menu (GpMainMenuApplet *main_menu)
+{
+  gchar *menu_path;
+  gchar *scheme;
+  gchar *path;
+
+  g_clear_object (&main_menu->menu);
+  g_clear_object (&main_menu->lock_logout);
+
+  menu_path = g_settings_get_string (main_menu->settings, "menu-path");
+
+  scheme = NULL;
+  path = split_menu_uri (menu_path, &scheme);
+  g_free (menu_path);
+
+  if (path != NULL)
+    {
+      gchar *menu_file;
+
+      menu_file = NULL;
+      if (validate_scheme (scheme, &menu_file))
+        {
+          main_menu->menu = gp_menu_new (GP_APPLET (main_menu), menu_file, TRUE);
+          gp_menu_set_path (GP_MENU (main_menu->menu), path);
+
+          main_menu->custom_menu = TRUE;
+
+          g_signal_connect_swapped (main_menu->menu, "loaded",
+                                    G_CALLBACK (update_icon), main_menu);
+        }
+
+      g_free (menu_file);
+      g_free (scheme);
+      g_free (path);
+    }
+
+  if (main_menu->menu == NULL)
+    {
+      gchar *menu_file;
+
+      menu_file = get_applications_menu ();
+      main_menu->menu = gp_menu_new (GP_APPLET (main_menu), menu_file, TRUE);
+      g_free (menu_file);
+
+      g_assert (main_menu->lock_logout == NULL);
+      main_menu->lock_logout = gp_lock_logout_new (GP_APPLET (main_menu));
+
+      g_signal_connect_swapped (main_menu->lock_logout, "changed",
+                                G_CALLBACK (gp_menu_reload), main_menu->menu);
+
+      gp_menu_set_append_func (GP_MENU (main_menu->menu),
+                               (GpAppendMenuItemsFunc) append_menu_items_cb,
+                               main_menu);
+
+      main_menu->custom_menu = FALSE;
+    }
+
+  g_object_ref_sink (main_menu->menu);
+}
+
+static void
+settings_changed_cb (GSettings        *settings,
+                     const gchar      *key,
+                     GpMainMenuApplet *main_menu)
+{
+  if (g_strcmp0 (key, "custom-icon") == 0)
+    {
+      update_icon (main_menu);
+    }
+  else if (g_strcmp0 (key, "menu-path") == 0)
+    {
+      update_menu (main_menu);
+      update_icon (main_menu);
+    }
+  else if (g_strcmp0 (key, "show-arrow") == 0)
+    {
+      gboolean show_arrow;
+
+      show_arrow = g_settings_get_boolean (main_menu->settings, "show-arrow");
+      gtk_widget_set_visible (main_menu->image, show_arrow);
+    }
+  else if (g_strcmp0 (key, "tooltip") == 0)
+    {
+      gchar *tooltip;
+      gboolean enable_tooltips;
+
+      tooltip = g_settings_get_string (main_menu->settings, "tooltip");
+      gtk_widget_set_tooltip_text (main_menu->button, *tooltip != '\0' ? tooltip : NULL);
+      g_free (tooltip);
+
+      g_object_get (main_menu, "enable-tooltips", &enable_tooltips, NULL);
+      gtk_widget_set_has_tooltip (main_menu->button, enable_tooltips);
+    }
+}
+
+static gint
+arrow_size_from_icon_size (guint icon_size)
+{
+  return 16 * (icon_size / 36.0);
+}
+
+static void
+panel_icon_size_cb (GpApplet         *applet,
+                    GParamSpec       *pspec,
+                    GpMainMenuApplet *main_menu)
+{
+  guint icon_size;
+  guint arrow_size;
+
+  icon_size = gp_applet_get_panel_icon_size (applet);
+  gtk_image_set_pixel_size (GTK_IMAGE (main_menu->image), icon_size);
+
+  arrow_size = arrow_size_from_icon_size (icon_size);
+  gtk_image_set_pixel_size (GTK_IMAGE (main_menu->arrow), arrow_size);
+}
+
 static void
 edit_menus_cb (GSimpleAction *action,
                GVariant      *parameter,
@@ -102,10 +506,107 @@ setup_menu (GpMainMenuApplet *main_menu)
   g_object_bind_property (applet, "locked-down", action, "enabled", flags);
 }
 
+static gboolean
+button_press_event_cb (GtkWidget        *widget,
+                       GdkEvent         *event,
+                       GpMainMenuApplet *main_menu)
+{
+  GdkEventButton *button;
+
+  if (event->type != GDK_BUTTON_PRESS)
+    return FALSE;
+
+  button = (GdkEventButton *) event;
+  if (button->button == GDK_BUTTON_SECONDARY)
+    return FALSE;
+
+  popup_menu (main_menu, event);
+
+  return TRUE;
+}
+
+static void
+clicked_cb (GtkWidget        *widget,
+            GpMainMenuApplet *main_menu)
+{
+  popup_menu (main_menu, NULL);
+}
+
+static void
+setup_button (GpMainMenuApplet *main_menu)
+{
+  GtkWidget *overlay;
+  gboolean show_arrow;
+  GtkStyleContext *style;
+  guint icon_size;
+  guint arrow_size;
+  gchar *tooltip;
+
+  main_menu->button = gp_menu_button_new ();
+  gtk_container_add (GTK_CONTAINER (main_menu), main_menu->button);
+  gtk_widget_show (main_menu->button);
+
+  g_signal_connect (main_menu->button, "button-press-event",
+                    G_CALLBACK (button_press_event_cb), main_menu);
+
+  g_signal_connect (main_menu->button, "clicked",
+                    G_CALLBACK (clicked_cb), main_menu);
+
+  overlay = gtk_overlay_new ();
+  gtk_container_add (GTK_CONTAINER (main_menu->button), overlay);
+  gtk_widget_set_halign (overlay, GTK_ALIGN_FILL);
+  gtk_widget_set_valign (overlay, GTK_ALIGN_FILL);
+  gtk_widget_show (overlay);
+
+  main_menu->image = gtk_image_new ();
+  gtk_container_add (GTK_CONTAINER (overlay), main_menu->image);
+  gtk_widget_show (main_menu->image);
+
+  style = gtk_widget_get_style_context (main_menu->image);
+  gtk_style_context_add_class (style, "icon");
+
+  show_arrow = g_settings_get_boolean (main_menu->settings, "show-arrow");
+
+  main_menu->arrow = gtk_image_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_MENU);
+  gtk_overlay_add_overlay (GTK_OVERLAY (overlay), main_menu->arrow);
+  gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), main_menu->arrow, TRUE);
+  gtk_widget_set_visible (main_menu->arrow, show_arrow);
+
+  style = gtk_widget_get_style_context (main_menu->arrow);
+  gtk_style_context_add_class (style, "arrow");
+
+  icon_size = gp_applet_get_panel_icon_size (GP_APPLET (main_menu));
+  gtk_image_set_pixel_size (GTK_IMAGE (main_menu->image), icon_size);
+
+  arrow_size = arrow_size_from_icon_size (icon_size);
+  gtk_image_set_pixel_size (GTK_IMAGE (main_menu->arrow), arrow_size);
+
+  tooltip = g_settings_get_string (main_menu->settings, "tooltip");
+  gtk_widget_set_tooltip_text (main_menu->button, *tooltip != '\0' ? tooltip : NULL);
+  g_free (tooltip);
+
+  g_object_bind_property (main_menu, "enable-tooltips",
+                          main_menu->button, "has-tooltip",
+                          G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+  update_menu (main_menu);
+  update_icon (main_menu);
+}
+
 static void
 gp_main_menu_applet_setup (GpMainMenuApplet *main_menu)
 {
+  main_menu->settings = gp_applet_settings_new (GP_APPLET (main_menu),
+                                                MAIN_MENU_SCHEMA);
+
+  g_signal_connect (main_menu->settings, "changed",
+                    G_CALLBACK (settings_changed_cb), main_menu);
+
+  g_signal_connect (main_menu, "notify::panel-icon-size",
+                    G_CALLBACK (panel_icon_size_cb), main_menu);
+
   setup_menu (main_menu);
+  setup_button (main_menu);
 }
 
 static void
@@ -115,14 +616,45 @@ gp_main_menu_applet_constructed (GObject *object)
   gp_main_menu_applet_setup (GP_MAIN_MENU_APPLET (object));
 }
 
+static void
+gp_main_menu_applet_dispose (GObject *object)
+{
+  GpMainMenuApplet *main_menu;
+
+  main_menu = GP_MAIN_MENU_APPLET (object);
+
+  g_clear_object (&main_menu->menu);
+  g_clear_object (&main_menu->lock_logout);
+  g_clear_object (&main_menu->settings);
+
+  G_OBJECT_CLASS (gp_main_menu_applet_parent_class)->dispose (object);
+}
+
+static void
+gp_main_menu_applet_placement_changed (GpApplet        *applet,
+                                       GtkOrientation   orientation,
+                                       GtkPositionType  position)
+{
+  GpMainMenuApplet *main_menu;
+
+  main_menu = GP_MAIN_MENU_APPLET (applet);
+
+  update_arrow (main_menu, position);
+}
+
 static void
 gp_main_menu_applet_class_init (GpMainMenuAppletClass *main_menu_class)
 {
   GObjectClass *object_class;
+  GpAppletClass *applet_class;
 
   object_class = G_OBJECT_CLASS (main_menu_class);
+  applet_class = GP_APPLET_CLASS (main_menu_class);
 
   object_class->constructed = gp_main_menu_applet_constructed;
+  object_class->dispose = gp_main_menu_applet_dispose;
+
+  applet_class->placement_changed = gp_main_menu_applet_placement_changed;
 }
 
 static void
diff --git a/modules/menu/gp-menu-button.c b/modules/menu/gp-menu-button.c
new file mode 100644
index 000000000..6febbd85c
--- /dev/null
+++ b/modules/menu/gp-menu-button.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "gp-menu-button.h"
+
+struct _GpMenuButton
+{
+  GtkButton parent;
+};
+
+G_DEFINE_TYPE (GpMenuButton, gp_menu_button, GTK_TYPE_BUTTON)
+
+static void
+gp_menu_button_class_init (GpMenuButtonClass *button_class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = GTK_WIDGET_CLASS (button_class);
+
+  gtk_widget_class_set_css_name (widget_class, "gp-menu-button");
+}
+
+static void
+gp_menu_button_init (GpMenuButton *button)
+{
+}
+
+GtkWidget *
+gp_menu_button_new (void)
+{
+  return g_object_new (GP_TYPE_MENU_BUTTON, NULL);
+}
diff --git a/modules/menu/gp-menu-button.h b/modules/menu/gp-menu-button.h
new file mode 100644
index 000000000..61e9edd91
--- /dev/null
+++ b/modules/menu/gp-menu-button.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GP_MENU_BUTTON_H
+#define GP_MENU_BUTTON_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GP_TYPE_MENU_BUTTON (gp_menu_button_get_type ())
+G_DECLARE_FINAL_TYPE (GpMenuButton, gp_menu_button, GP, MENU_BUTTON, GtkButton)
+
+GtkWidget *gp_menu_button_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/modules/menu/gp-menu-module.c b/modules/menu/gp-menu-module.c
index 882c919b1..bd435cfc8 100644
--- a/modules/menu/gp-menu-module.c
+++ b/modules/menu/gp-menu-module.c
@@ -89,7 +89,7 @@ gp_module_load (GpModule *module)
   gp_module_set_id (module, "org.gnome.gnome-panel.menu");
   gp_module_set_version (module, PACKAGE_VERSION);
 
-  gp_module_set_applet_ids (module, "menu-bar", "user-menu", NULL);
+  gp_module_set_applet_ids (module, "menu-bar", "main-menu", "user-menu", NULL);
 
   gp_module_set_get_applet_info (module, menu_get_applet_info);
   gp_module_set_compatibility (module, menu_get_applet_id_from_iid);
diff --git a/modules/menu/org.gnome.gnome-panel.applet.main-menu.gschema.xml 
b/modules/menu/org.gnome.gnome-panel.applet.main-menu.gschema.xml
new file mode 100644
index 000000000..e74729998
--- /dev/null
+++ b/modules/menu/org.gnome.gnome-panel.applet.main-menu.gschema.xml
@@ -0,0 +1,26 @@
+<schemalist gettext-domain="gnome-panel">
+  <schema id="org.gnome.gnome-panel.applet.main-menu">
+    <key name="custom-icon" type="s">
+      <default>''</default>
+      <summary>Icon used for button</summary>
+      <description>The location of the image file used as the icon for the object's button. If empty, the 
default icon for the menu will be used.</description>
+    </key>
+
+    <key name="menu-path" type="s">
+      <default>''</default>
+      <summary>Menu content path</summary>
+      <description>The path from which the menu contents is constructed. If empty, the menu will be the 
default applications menu.</description>
+    </key>
+
+    <key name="show-arrow" type="b">
+      <default>true</default>
+      <summary>Show arrow on menu icon</summary>
+    </key>
+
+    <key name="tooltip" type="s">
+      <default>''</default>
+      <summary>Tooltip displayed for menu</summary>
+      <description>The text to display in a tooltip for this menu.</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 477230149..2a0eafc59 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -68,6 +68,7 @@ modules/menu/gp-places-menu.c
 modules/menu/gp-recent-menu.c
 modules/menu/main-menu-menu.ui
 modules/menu/menu-bar-menu.ui
+modules/menu/org.gnome.gnome-panel.applet.main-menu.gschema.xml
 modules/notification-area/na-applet.c
 modules/notification-area/na-module.c
 modules/notification-area/na-tray-manager.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]