← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~bratsche/dbusmenu/menubar into lp:dbusmenu

 

Cody Russell has proposed merging lp:~bratsche/dbusmenu/menubar into lp:dbusmenu.

    Requested reviews:
    DBus Menu Team (dbusmenu-team)
Related bugs:
  #458732 Menubars ftw
  https://bugs.launchpad.net/bugs/458732

-- 
https://code.launchpad.net/~bratsche/dbusmenu/menubar/+merge/13817
Your team ayatana-commits is subscribed to branch lp:dbusmenu.
=== modified file 'libdbusmenu-gtk/Makefile.am'
--- libdbusmenu-gtk/Makefile.am	2009-10-01 19:22:18 +0000
+++ libdbusmenu-gtk/Makefile.am	2009-10-23 03:40:22 +0000
@@ -10,6 +10,7 @@
 libdbusmenu_gtkinclude_HEADERS = \
 	client.h \
 	menu.h \
+	menubar.h \
 	menuitem.h
 
 libdbusmenu_gtk_la_SOURCES = \
@@ -17,6 +18,8 @@
 	client.c \
 	menu.h \
 	menu.c \
+	menubar.h \
+	menubar.c \
 	menuitem.h \
 	menuitem.c
 

=== added file 'libdbusmenu-gtk/menubar.c'
--- libdbusmenu-gtk/menubar.c	1970-01-01 00:00:00 +0000
+++ libdbusmenu-gtk/menubar.c	2009-10-23 03:40:22 +0000
@@ -0,0 +1,342 @@
+/*
+A library to take the object model made consistent by libdbusmenu-glib
+and visualize it in GTK.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+    Cody Russell <crussell@xxxxxxxxxxxxx>
+    Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program.  If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+
+#include "menubar.h"
+#include "libdbusmenu-glib/client.h"
+#include "client.h"
+
+/* Properties */
+enum {
+        PROP_0,
+        PROP_DBUSOBJECT,
+        PROP_DBUSNAME
+};
+
+/* Private */
+struct _DbusmenuGtkmenubarPrivate {
+        DbusmenuGtkClient *client;
+
+        gchar *dbus_object;
+        gchar *dbus_name;
+};
+
+#define DBUSMENU_GTKMENUBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_GTKMENUBAR_TYPE, DbusmenuGtkmenubarPrivate))
+
+/* Prototypes */
+static void dbusmenu_gtkmenubar_class_init   (DbusmenuGtkmenubarClass *klass);
+static void dbusmenu_gtkmenubar_init         (DbusmenuGtkmenubar      *self);
+static void dbusmenu_gtkmenubar_dispose      (GObject                 *object);
+static void dbusmenu_gtkmenubar_finalize     (GObject                 *object);
+static void dbusmenu_gtkmenubar_set_property (GObject                 *obj,
+                                              guint                    id,
+                                              const GValue            *value,
+                                              GParamSpec              *pspec);
+static void dbusmenu_gtkmenubar_get_property (GObject                 *obj,
+                                              guint                    id,
+                                              GValue                  *value,
+                                              GParamSpec              *pspec);
+
+static void build_client   (DbusmenuGtkmenubar *self);
+static void child_realized (DbusmenuMenuitem   *child,
+                            gpointer            userdata);
+
+G_DEFINE_TYPE (DbusmenuGtkmenubar, dbusmenu_gtkmenubar, GTK_TYPE_MENU_BAR);
+
+static void
+dbusmenu_gtkmenubar_class_init (DbusmenuGtkmenubarClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        g_type_class_add_private (klass, sizeof (DbusmenuGtkmenubarPrivate));
+
+        object_class->dispose = dbusmenu_gtkmenubar_dispose;
+        object_class->finalize = dbusmenu_gtkmenubar_finalize;
+        object_class->set_property = dbusmenu_gtkmenubar_set_property;
+        object_class->get_property = dbusmenu_gtkmenubar_get_property;
+
+        g_object_class_install_property (object_class,
+                                         PROP_DBUSOBJECT,
+                                         g_param_spec_string (DBUSMENU_CLIENT_PROP_DBUS_OBJECT,
+                                                              "DBus Object we represent",
+                                                              "The Object on the client that we're getting our data from.",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property (object_class,
+                                         PROP_DBUSNAME,
+                                         g_param_spec_string (DBUSMENU_CLIENT_PROP_DBUS_NAME,
+                                                              "DBus Client we connect to",
+                                                              "Name of the DBus client we're connecting to.",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+dbusmenu_gtkmenubar_init (DbusmenuGtkmenubar *self)
+{
+        DbusmenuGtkmenubarPrivate *priv = self->priv = DBUSMENU_GTKMENUBAR_GET_PRIVATE (self);
+
+        priv->client = NULL;
+
+        priv->dbus_object = NULL;
+        priv->dbus_name = NULL;
+}
+
+static void
+dbusmenu_gtkmenubar_dispose (GObject *object)
+{
+        DbusmenuGtkmenubar *menubar = DBUSMENU_GTKMENUBAR (object);
+
+        if (menubar->priv->client != NULL) {
+                g_object_unref (G_OBJECT (menubar->priv->client));
+	        menubar->priv->client = NULL;
+        }
+
+        G_OBJECT_CLASS (dbusmenu_gtkmenubar_parent_class)->dispose (object);
+}
+
+static void
+dbusmenu_gtkmenubar_finalize (GObject *object)
+{
+        DbusmenuGtkmenubar *menubar = DBUSMENU_GTKMENUBAR (object);
+
+        g_free (menubar->priv->dbus_object);
+        menubar->priv->dbus_object = NULL;
+
+        g_free (menubar->priv->dbus_name);
+        menubar->priv->dbus_name = NULL;
+
+        G_OBJECT_CLASS (dbusmenu_gtkmenubar_parent_class)->finalize (object);
+}
+
+static void
+dbusmenu_gtkmenubar_set_property (GObject *obj, guint id, const GValue *value, GParamSpec *pspec)
+{
+        DbusmenuGtkmenubar *menubar = DBUSMENU_GTKMENUBAR (obj);
+
+        switch (id) {
+        case PROP_DBUSNAME:
+                menubar->priv->dbus_name = g_value_dup_string (value);
+
+                if (menubar->priv->dbus_name != NULL && menubar->priv->dbus_object != NULL) {
+                        build_client (menubar);
+                }
+
+                break;
+
+        case PROP_DBUSOBJECT:
+                menubar->priv->dbus_object = g_value_dup_string (value);
+
+                if (menubar->priv->dbus_name != NULL && menubar->priv->dbus_object != NULL) {
+                        build_client (menubar);
+                }
+
+                break;
+
+        default:
+                g_warning ("Unknown property %d.", id);
+                return;
+        }
+}
+
+static void
+dbusmenu_gtkmenubar_get_property (GObject *obj, guint id, GValue *value, GParamSpec *pspec)
+{
+        DbusmenuGtkmenubar *menubar = DBUSMENU_GTKMENUBAR (obj);
+
+        switch (id) {
+        case PROP_DBUSNAME:
+                g_value_set_string (value, menubar->priv->dbus_name);
+                break;
+
+        case PROP_DBUSOBJECT:
+                g_value_set_string (value, menubar->priv->dbus_object);
+                break;
+
+        default:
+                g_warning("Unknown property %d.", id);
+                return;
+        }
+}
+
+static void
+root_child_added (DbusmenuMenuitem *root,
+                  DbusmenuMenuitem *child,
+                  guint position,
+                  DbusmenuGtkmenubar *menubar)
+{
+        GtkMenuItem *mi;
+
+        g_signal_connect (G_OBJECT (child),
+                          DBUSMENU_MENUITEM_SIGNAL_REALIZED,
+                          G_CALLBACK (child_realized), menubar);
+
+        mi = dbusmenu_gtkclient_menuitem_get (menubar->priv->client, child);
+
+        if (mi != NULL) {
+                gtk_menu_insert (GTK_MENU_BAR (menubar),
+                                 GTK_WIDGET (mi),
+                                 position);
+	}
+}
+
+static void
+root_child_moved (DbusmenuMenuitem *root,
+                  DbusmenuMenuitem *child,
+                  guint newposition,
+                  guint oldposition,
+                  DbusmenuGtkmenubar *menubar)
+{
+        gtk_menu_reorder_child (GTK_MENU (menubar),
+                                GTK_WIDGET (dbusmenu_gtkclient_menuitem_get (menubar->priv->client, child)), newposition);
+}
+
+static void
+root_child_delete (DbusmenuMenuitem   *root,
+                   DbusmenuMenuitem   *child,
+                   DbusmenuGtkmenubar *menubar)
+{
+        GtkWidget *item = GTK_WIDGET (dbusmenu_gtkclient_menuitem_get (menubar->priv->client, child));
+
+        if (item != NULL) {
+                gtk_container_remove (GTK_CONTAINER (menubar), item);
+        }
+
+        if (g_list_length (dbusmenu_menuitem_get_children (root)) == 0) {
+                gtk_widget_hide (GTK_WIDGET (menubar));
+        }
+}
+
+static void
+child_realized (DbusmenuMenuitem *child,
+                gpointer userdata)
+{
+        g_return_if_fail (DBUSMENU_IS_GTKMENUBAR (userdata));
+
+        DbusmenuGtkmenubar *menubar = DBUSMENU_GTKMENUBAR (userdata);
+
+        GtkWidget *child_widget = GTK_WIDGET (dbusmenu_gtkclient_menuitem_get (menubar->priv->client, child));
+
+        if (child_widget != NULL) {
+                gtk_menu_shell_insert (GTK_MENU_SHELL (menubar),
+                                       child_widget,
+                                       dbusmenu_menuitem_get_position (child, dbusmenu_client_get_root (DBUSMENU_CLIENT (menubar->priv->client))));
+        } else {
+                g_warning ("Child is realized, but doesn't have a GTK Widget!");
+        }
+}
+
+static void
+root_changed (DbusmenuGtkClient *client, DbusmenuMenuitem *newroot, DbusmenuGtkmenubar *menu) {
+        GList *child = NULL;
+        guint count = 0;
+
+        if (newroot == NULL) {
+                gtk_widget_hide (GTK_WIDGET (menu));
+
+                return;
+        }
+
+        g_signal_connect (G_OBJECT (newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED,   G_CALLBACK (root_child_added),  menu);
+        g_signal_connect (G_OBJECT (newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED,   G_CALLBACK (root_child_moved),  menu);
+        g_signal_connect (G_OBJECT (newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK (root_child_delete), menu);
+
+        for (child = dbusmenu_menuitem_get_children (newroot); child != NULL; child = g_list_next (child)) {
+                /* gtk_menu_append(menu, GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(client, child->data))); */
+                g_signal_connect (G_OBJECT (child->data),
+                                  DBUSMENU_MENUITEM_SIGNAL_REALIZED,
+                                  G_CALLBACK (child_realized),
+                                  menu);
+                count++;
+        }
+
+        if (count > 0) {
+                gtk_widget_show (GTK_WIDGET (menu));
+        } else {
+                gtk_widget_hide (GTK_WIDGET (menu));
+        }
+}
+
+static void
+build_client (DbusmenuGtkmenubar *self)
+{
+        if (self->priv->client == NULL) {
+                self->priv->client = dbusmenu_gtkclient_new (self->priv->dbus_name,
+                                                             self->priv->dbus_object);
+
+                g_signal_connect (G_OBJECT (self->priv->client),
+                                  DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED,
+                                  G_CALLBACK (root_changed),
+                                  self);
+        }
+}
+
+/* Public API */
+
+/**
+	dbusmenu_gtkmenubar_new:
+	@dbus_name: Name of the #DbusmenuServer on DBus
+	@dbus_name: Name of the object on the #DbusmenuServer
+
+	Creates a new #DbusmenuGtkmenubar object and creates a #DbusmenuClient
+	that connects across DBus to a #DbusmenuServer.
+
+	Return value: A new #DbusmenuGtkmenubar sync'd with a server
+*/
+DbusmenuGtkmenubar *
+dbusmenu_gtkmenubar_new (gchar *dbus_name, gchar *dbus_object)
+{
+        return g_object_new (DBUSMENU_GTKMENUBAR_TYPE,
+                             DBUSMENU_CLIENT_PROP_DBUS_OBJECT, dbus_object,
+                             DBUSMENU_CLIENT_PROP_DBUS_NAME, dbus_name,
+                             NULL);
+}
+
+/**
+	dbusmenu_gtkmenubar_get_client:
+	@menu: The #DbusmenuGtkmenubar to get the client from
+
+	An accessor for the client that this menu is using to
+	communicate with the server.
+
+	Return value: A valid #DbusmenuGtkClient or NULL on error.
+*/
+DbusmenuGtkClient *
+dbusmenu_gtkmenubar_get_client (DbusmenuGtkmenubar *menubar)
+{
+        g_return_val_if_fail (DBUSMENU_IS_GTKMENUBAR (menubar), NULL);
+
+        return menubar->priv->client;
+}

=== added file 'libdbusmenu-gtk/menubar.h'
--- libdbusmenu-gtk/menubar.h	1970-01-01 00:00:00 +0000
+++ libdbusmenu-gtk/menubar.h	2009-10-23 03:40:22 +0000
@@ -0,0 +1,96 @@
+/*
+A library to take the object model made consistent by libdbusmenu-glib
+and visualize it in GTK.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+    Cody Russell <crussell@xxxxxxxxxxxxx>
+    Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program.  If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#ifndef __DBUSMENU_GTKMENUBAR_H__
+#define __DBUSMENU_GTKMENUBAR_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include "client.h"
+
+G_BEGIN_DECLS
+
+typedef struct _DbusmenuGtkmenubar        DbusmenuGtkmenubar;
+typedef struct _DbusmenuGtkmenubarClass   DbusmenuGtkmenubarClass;
+typedef struct _DbusmenuGtkmenubarPrivate DbusmenuGtkmenubarPrivate;
+
+#define DBUSMENU_GTKMENUBAR_TYPE            (dbusmenu_gtkmenubar_get_type ())
+#define DBUSMENU_GTKMENUBAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_GTKMENUBAR_TYPE, DbusmenuGtkmenubar))
+#define DBUSMENU_GTKMENUBAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_GTKMENUBAR_TYPE, DbusmenuGtkmenubarClass))
+#define DBUSMENU_IS_GTKMENUBAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_GTKMENUBAR_TYPE))
+#define DBUSMENU_IS_GTKMENUBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_GTKMENUBAR_TYPE))
+#define DBUSMENU_GTKMENUBAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_GTKMENUBAR_TYPE, DbusmenuGtkmenubarClass))
+
+struct _DbusmenuGtkmenubarClass {
+	GtkMenuBarClass parent_class;
+
+	/* Reserved */
+	void (*reserved1) (void);
+	void (*reserved2) (void);
+	void (*reserved3) (void);
+	void (*reserved4) (void);
+};
+
+struct _DbusmenuGtkmenubar {
+        GtkMenuBar parent;
+        DbusmenuGtkmenubarPrivate *priv;
+};
+
+GType               dbusmenu_gtkmenubar_get_type   (void) G_GNUC_CONST;
+DbusmenuGtkmenubar *dbusmenu_gtkmenubar_new        (gchar *dbus_name, gchar *dbus_object);
+DbusmenuGtkClient  *dbusmenu_gtkmenubar_get_client (DbusmenuGtkmenubar *menu);
+
+/**
+	SECTION:gtkmenubar
+	@short_description: A GTK Menubar Object that syncronizes over DBus
+	@stability: Unstable
+	@include: libdbusmenu-gtk/menubar.h
+
+	In general, this is just a #GtkMenuBar, why else would you care?  Oh,
+	because this menu is created by someone else on a server that exists
+	on the other side of DBus.  You need a #DbusmenuServer to be able
+	push the data into this menu.
+
+	The first thing you need to know is how to find that #DbusmenuServer
+	on DBus.  This involves both the DBus name and the DBus object that
+	the menu interface can be found on.  Those two value should be set
+	when creating the object using dbusmenu_gtkmenubar_new().  They are then
+	stored on two properties #DbusmenuGtkmenubar:dbus-name and #DbusmenuGtkmenubar:dbus-object.
+
+	After creation the #DbusmenuGtkmenubar it will continue to keep in
+	synchronization with the #DbusmenuServer object across Dbus.  If the
+	number of entries change, the menus change, if they change thier
+	properties change, they update in the items.  All of this should
+	be handled transparently to the user of this object.
+
+	TODO: Document properties.
+*/
+G_END_DECLS
+
+#endif