diff options
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r-- | libdbusmenu-glib/Makefile.am | 15 | ||||
-rw-r--r-- | libdbusmenu-glib/Makefile.in | 15 | ||||
-rw-r--r-- | libdbusmenu-glib/client-marshal.c | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/client-marshal.h | 3 | ||||
-rw-r--r-- | libdbusmenu-glib/client-marshal.list | 1 | ||||
-rw-r--r-- | libdbusmenu-glib/client.c | 82 | ||||
-rw-r--r-- | libdbusmenu-glib/client.h | 25 | ||||
-rw-r--r-- | libdbusmenu-glib/dbus-menu-clean.xml.c | 14 | ||||
-rw-r--r-- | libdbusmenu-glib/dbus-menu.xml | 38 | ||||
-rw-r--r-- | libdbusmenu-glib/defaults.c | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 76 | ||||
-rw-r--r-- | libdbusmenu-glib/server.c | 111 | ||||
-rw-r--r-- | libdbusmenu-glib/server.h | 3 |
13 files changed, 292 insertions, 95 deletions
diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am index 8b523aa..5b04415 100644 --- a/libdbusmenu-glib/Makefile.am +++ b/libdbusmenu-glib/Makefile.am @@ -17,12 +17,17 @@ lib_LTLIBRARIES = \ libdbusmenu_glibincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-glib/ -libdbusmenu_glibinclude_HEADERS = \ - dbusmenu-glib.h \ + +EXPORTED_OBJECTS = \ + enum-types.h \ menuitem.h \ menuitem-proxy.h \ server.h \ - client.h \ + client.h + +libdbusmenu_glibinclude_HEADERS = \ + $(EXPORTED_OBJECTS) \ + dbusmenu-glib.h \ types.h libdbusmenu_glib_la_SOURCES = \ @@ -153,7 +158,9 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) if HAVE_INTROSPECTION -introspection_sources = $(libdbusmenu_glibinclude_HEADERS) $(libdbusmenu_glib_la_SOURCES) +introspection_sources = \ + $(libdbusmenu_glibinclude_HEADERS) \ + $(EXPORTED_OBJECTS:.h=.c) Dbusmenu-0.4.gir: libdbusmenu-glib.la Dbusmenu_0_4_gir_INCLUDES = \ diff --git a/libdbusmenu-glib/Makefile.in b/libdbusmenu-glib/Makefile.in index f81497b..e2b9157 100644 --- a/libdbusmenu-glib/Makefile.in +++ b/libdbusmenu-glib/Makefile.in @@ -340,12 +340,16 @@ lib_LTLIBRARIES = \ libdbusmenu-glib.la libdbusmenu_glibincludedir = $(includedir)/libdbusmenu-0.4/libdbusmenu-glib/ -libdbusmenu_glibinclude_HEADERS = \ - dbusmenu-glib.h \ +EXPORTED_OBJECTS = \ + enum-types.h \ menuitem.h \ menuitem-proxy.h \ server.h \ - client.h \ + client.h + +libdbusmenu_glibinclude_HEADERS = \ + $(EXPORTED_OBJECTS) \ + dbusmenu-glib.h \ types.h libdbusmenu_glib_la_SOURCES = \ @@ -404,7 +408,10 @@ INTROSPECTION_GIRS = $(am__append_1) @INTROSPECTION_TEN_TRUE@ --identifier-prefix=Dbusmenu INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) -@HAVE_INTROSPECTION_TRUE@introspection_sources = $(libdbusmenu_glibinclude_HEADERS) $(libdbusmenu_glib_la_SOURCES) +@HAVE_INTROSPECTION_TRUE@introspection_sources = \ +@HAVE_INTROSPECTION_TRUE@ $(libdbusmenu_glibinclude_HEADERS) \ +@HAVE_INTROSPECTION_TRUE@ $(EXPORTED_OBJECTS:.h=.c) + @HAVE_INTROSPECTION_TRUE@Dbusmenu_0_4_gir_INCLUDES = \ @HAVE_INTROSPECTION_TRUE@ GObject-2.0 diff --git a/libdbusmenu-glib/client-marshal.c b/libdbusmenu-glib/client-marshal.c index 60d7bd6..0614b69 100644 --- a/libdbusmenu-glib/client-marshal.c +++ b/libdbusmenu-glib/client-marshal.c @@ -131,3 +131,5 @@ _dbusmenu_client_marshal_VOID__OBJECT_STRING_VARIANT_UINT_POINTER (GClosure /* VOID:ENUM (./client-marshal.list:3) */ +/* VOID:POINTER (./client-marshal.list:4) */ + diff --git a/libdbusmenu-glib/client-marshal.h b/libdbusmenu-glib/client-marshal.h index c12af7c..121e096 100644 --- a/libdbusmenu-glib/client-marshal.h +++ b/libdbusmenu-glib/client-marshal.h @@ -25,6 +25,9 @@ extern void _dbusmenu_client_marshal_VOID__OBJECT_STRING_VARIANT_UINT_POINTER (G /* VOID:ENUM (./client-marshal.list:3) */ #define _dbusmenu_client_marshal_VOID__ENUM g_cclosure_marshal_VOID__ENUM +/* VOID:POINTER (./client-marshal.list:4) */ +#define _dbusmenu_client_marshal_VOID__POINTER g_cclosure_marshal_VOID__POINTER + G_END_DECLS #endif /* ___dbusmenu_client_marshal_MARSHAL_H__ */ diff --git a/libdbusmenu-glib/client-marshal.list b/libdbusmenu-glib/client-marshal.list index 96f9302..980c5c3 100644 --- a/libdbusmenu-glib/client-marshal.list +++ b/libdbusmenu-glib/client-marshal.list @@ -1,3 +1,4 @@ VOID: OBJECT, UINT VOID: OBJECT, STRING, VARIANT, UINT, POINTER VOID: ENUM +VOID: POINTER diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index d368a0e..c95b161 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -62,6 +62,7 @@ enum { NEW_MENUITEM, ITEM_ACTIVATE, EVENT_RESULT, + ICON_THEME_DIRS, LAST_SIGNAL }; @@ -98,6 +99,7 @@ struct _DbusmenuClientPrivate DbusmenuTextDirection text_direction; DbusmenuStatus status; + GStrv icon_dirs; }; typedef struct _newItemPropData newItemPropData; @@ -129,7 +131,7 @@ typedef struct _type_handler_t type_handler_t; struct _type_handler_t { DbusmenuClient * client; DbusmenuClientTypeHandler cb; - DbusmenuClientTypeDestroyHandler destroy_cb; + GDestroyNotify destroy_cb; gpointer user_data; gchar * type; }; @@ -272,6 +274,20 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass) NULL, NULL, _dbusmenu_client_marshal_VOID__OBJECT_STRING_VARIANT_UINT_POINTER, G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_UINT, G_TYPE_POINTER); + /** + DbusmenuClient::icon-theme-dirs-changed: + @arg0: The #DbusmenuClient object + @arg1: A #GStrv of theme directories + + Signaled when the theme directories are changed by the server. + */ + signals[ICON_THEME_DIRS] = g_signal_new(DBUSMENU_CLIENT_SIGNAL_ICON_THEME_DIRS_CHANGED, + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DbusmenuClientClass, icon_theme_dirs), + NULL, NULL, + _dbusmenu_client_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); g_object_class_install_property (object_class, PROP_DBUSOBJECT, g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", @@ -358,6 +374,7 @@ dbusmenu_client_init (DbusmenuClient *self) priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE; priv->status = DBUSMENU_STATUS_NORMAL; + priv->icon_dirs = NULL; return; } @@ -466,6 +483,11 @@ dbusmenu_client_finalize (GObject *object) g_hash_table_destroy(priv->type_handlers); } + if (priv->icon_dirs != NULL) { + g_strfreev(priv->icon_dirs); + priv->icon_dirs = NULL; + } + G_OBJECT_CLASS (dbusmenu_client_parent_class)->finalize (object); return; } @@ -1026,7 +1048,7 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data) } /* Check the text direction if available */ - GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "text-direction"); + GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "TextDirection"); if (textdir != NULL) { GVariant * str = textdir; if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) { @@ -1064,17 +1086,25 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); DbusmenuTextDirection olddir = priv->text_direction; DbusmenuStatus oldstatus = priv->status; + gboolean dirs_changed = FALSE; /* Invalidate first */ gchar * invalid; gint i = 0; for (invalid = invalidated[i]; invalid != NULL; invalid = invalidated[++i]) { - if (g_strcmp0(invalid, "text-direction") == 0) { + if (g_strcmp0(invalid, "TextDirection") == 0) { priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE; } - if (g_strcmp0(invalid, "status") == 0) { + if (g_strcmp0(invalid, "Status") == 0) { priv->status = DBUSMENU_STATUS_NORMAL; } + if (g_strcmp0(invalid, "IconThemePath") == 0) { + if (priv->icon_dirs != NULL) { + dirs_changed = TRUE; + g_strfreev(priv->icon_dirs); + priv->icon_dirs = NULL; + } + } } /* Check updates */ @@ -1082,7 +1112,7 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva gchar * key; GVariant * value; g_variant_iter_init(&iters, properties); while (g_variant_iter_next(&iters, "{sv}", &key, &value)) { - if (g_strcmp0(key, "text-direction") == 0) { + if (g_strcmp0(key, "TextDirection") == 0) { GVariant * str = value; if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) { str = g_variant_get_variant(str); @@ -1090,7 +1120,7 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL)); } - if (g_strcmp0(key, "status") == 0) { + if (g_strcmp0(key, "Status") == 0) { GVariant * str = value; if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) { str = g_variant_get_variant(str); @@ -1098,6 +1128,15 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL)); } + if (g_strcmp0(key, "IconThemePath") == 0) { + if (priv->icon_dirs != NULL) { + g_strfreev(priv->icon_dirs); + priv->icon_dirs = NULL; + } + + priv->icon_dirs = g_variant_dup_strv(value, NULL); + dirs_changed = TRUE; + } g_variant_unref(value); g_free(key); @@ -1111,6 +1150,10 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS); } + if (dirs_changed) { + g_signal_emit(G_OBJECT(user_data), signals[ICON_THEME_DIRS], 0, priv->icon_dirs, TRUE); + } + return; } @@ -1168,7 +1211,7 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian gchar * property; while (g_variant_iter_next(&properties, "s", &property)) { - g_debug("Removing property '%s' on %d", property, id); + /* g_debug("Removing property '%s' on %d", property, id); */ dbusmenu_menuitem_property_remove(menuitem, property); } } @@ -1881,7 +1924,7 @@ type_handler_destroy (gpointer user_data) { type_handler_t * th = (type_handler_t *)user_data; if (th->destroy_cb != NULL) { - th->destroy_cb(th->client, th->type, th->user_data); + th->destroy_cb(th->user_data); } g_free(th->type); g_free(th); @@ -1893,7 +1936,7 @@ type_handler_destroy (gpointer user_data) * @client: Client where we're getting types coming in * @type: A text string that will be matched with the 'type' * property on incoming menu items - * @newfunc: The function that will be executed with those new + * @newfunc: (scope notified): The function that will be executed with those new * items when they come in. * * This function connects into the type handling of the #DbusmenuClient. @@ -1920,7 +1963,7 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D * @client: Client where we're getting types coming in * @type: A text string that will be matched with the 'type' * property on incoming menu items - * @newfunc: The function that will be executed with those new + * @newfunc: (scope notified): The function that will be executed with those new * items when they come in. * @user_data: Data passed to @newfunc when it is called * @destroy_func: A function that is called when the type handler is @@ -1941,7 +1984,7 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D * Return value: If registering the new type was successful. */ gboolean -dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destroy_func) +dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, GDestroyNotify destroy_func) { g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE); g_return_val_if_fail(type != NULL, FALSE); @@ -2012,4 +2055,21 @@ dbusmenu_client_get_status (DbusmenuClient * client) return priv->status; } +/** + * dbusmenu_client_get_icon_paths: + * @client: The #DbusmenuClient to get the icon paths from + * + * Gets the stored and exported icon paths from the client. + * + * Return value: (transfer none): A NULL-terminated list of icon paths with + * memory managed by the client. Duplicate if you want + * to keep them. + */ +const GStrv +dbusmenu_client_get_icon_paths (DbusmenuClient * client) +{ + g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), NULL); + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + return priv->icon_dirs; +} diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h index 28d4dd3..1cb9ee5 100644 --- a/libdbusmenu-glib/client.h +++ b/libdbusmenu-glib/client.h @@ -75,11 +75,11 @@ G_BEGIN_DECLS */ #define DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT "event-result" /** - * DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED: + * DBUSMENU_CLIENT_SIGNAL_ICON_THEME_DIRS_CHANGED: * - * String to attach to signal #DbusmenuClient::text-direction-changed + * String to attach to signal #DbusmenuClient::icon-theme-dirs-changed */ -#define DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED "text-direction-changed" +#define DBUSMENU_CLIENT_SIGNAL_ICON_THEME_DIRS_CHANGED "icon-theme-dirs-changed" /** * DBUSMENU_CLIENT_PROP_DBUS_NAME: @@ -139,12 +139,12 @@ typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate; @new_menuitem: Slot for #DbusmenuClient::new-menuitem. @item_activate: Slot for #DbusmenuClient::item-activate. @event_result: Slot for #DbusmenuClient::event-error. + @icon_theme_dirs: Slot for #DbusmenuClient::icon-theme-dirs-changed. @reserved1: Reserved for future use. @reserved2: Reserved for future use. @reserved3: Reserved for future use. @reserved4: Reserved for future use. @reserved5: Reserved for future use. - @reserved6: Reserved for future use. A simple class that takes all of the information from a #DbusmenuServer over DBus and makes the same set of @@ -159,6 +159,7 @@ struct _DbusmenuClientClass { void (*new_menuitem) (DbusmenuMenuitem * newitem); void (*item_activate) (DbusmenuMenuitem * item, guint timestamp); void (*event_result) (DbusmenuMenuitem * item, gchar * event, GVariant * data, guint timestamp, GError * error); + void (*icon_theme_dirs) (DbusmenuMenuitem * item, gpointer theme_dirs, GError * error); /*< Private >*/ void (*reserved1) (void); @@ -166,7 +167,6 @@ struct _DbusmenuClientClass { void (*reserved3) (void); void (*reserved4) (void); void (*reserved5) (void); - void (*reserved6) (void); }; /** @@ -198,18 +198,6 @@ struct _DbusmenuClient { */ typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); -/** - DbusmenuClientTypeDestroyHandler: - @client: A pointer to the #DbusmenuClient - @type: The type that this handler was registered with - @user_data: The data you gave us - - This handler is called when the type becomes unregistered by the - client. This is usally caused by the #DbusmenuClient being destroyed - and should free memory or unref objects in @user_data. -*/ -typedef void (*DbusmenuClientTypeDestroyHandler) (DbusmenuClient * client, const gchar * type, gpointer user_data); - GType dbusmenu_client_get_type (void); DbusmenuClient * dbusmenu_client_new (const gchar * name, const gchar * object); @@ -221,9 +209,10 @@ gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * cli const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, - DbusmenuClientTypeDestroyHandler destroy_func); + GDestroyNotify destroy_func); DbusmenuTextDirection dbusmenu_client_get_text_direction (DbusmenuClient * client); DbusmenuStatus dbusmenu_client_get_status (DbusmenuClient * client); +const GStrv dbusmenu_client_get_icon_paths (DbusmenuClient * client); /** SECTION:client diff --git a/libdbusmenu-glib/dbus-menu-clean.xml.c b/libdbusmenu-glib/dbus-menu-clean.xml.c index 215c19c..890f24c 100644 --- a/libdbusmenu-glib/dbus-menu-clean.xml.c +++ b/libdbusmenu-glib/dbus-menu-clean.xml.c @@ -6,15 +6,19 @@ const char * dbus_menu_clean_xml = " \n" "\n" "\n" -" <property name=\"version\" type=\"u\" access=\"read\">\n" +" <property name=\"Version\" type=\"u\" access=\"read\">\n" " \n" " </property>\n" "\n" -" <property name=\"text-direction\" type=\"s\" access=\"read\">\n" +" <property name=\"TextDirection\" type=\"s\" access=\"read\">\n" " \n" " </property>\n" "\n" -" <property name=\"status\" type=\"s\" access=\"read\">\n" +" <property name=\"Status\" type=\"s\" access=\"read\">\n" +" \n" +" </property>\n" +"\n" +" <property name=\"IconThemePath\" type=\"as\" access=\"read\">\n" " \n" " </property>\n" "\n" @@ -25,7 +29,7 @@ const char * dbus_menu_clean_xml = " <arg type=\"i\" name=\"parentId\" direction=\"in\">\n" " \n" " </arg>\n" -" <arg type=\"i\" name=\"recurse\" direction=\"in\">\n" +" <arg type=\"i\" name=\"recursionDepth\" direction=\"in\">\n" " \n" " </arg>\n" " <arg type=\"as\" name=\"propertyNames\" direction=\"in\">\n" @@ -40,8 +44,6 @@ const char * dbus_menu_clean_xml = " </method>\n" "\n" " <method name=\"GetGroupProperties\">\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QVariantList\"/>\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"DBusMenuItemList\"/>\n" " \n" " <arg type=\"ai\" name=\"ids\" direction=\"in\">\n" " \n" diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml index 0d2a2d6..efb55d4 100644 --- a/libdbusmenu-glib/dbus-menu.xml +++ b/libdbusmenu-glib/dbus-menu.xml @@ -164,14 +164,14 @@ License version 3 and version 2.1 along with this program. If not, see ]]></dox:d> <!-- Properties --> - <property name="version" type="u" access="read"> + <property name="Version" type="u" access="read"> <dox:d> Provides the version of the DBusmenu API that this API is implementing. </dox:d> </property> - <property name="text-direction" type="s" access="read"> + <property name="TextDirection" type="s" access="read"> <dox:d> Represents the way the text direction of the application. This allows the server to handle mismatches intelligently. For left- @@ -179,7 +179,7 @@ License version 3 and version 2.1 along with this program. If not, see </dox:d> </property> - <property name="status" type="s" access="read"> + <property name="Status" type="s" access="read"> <dox:d> Tells if the menus are in a normal state or they believe that they could use some attention. Cases for showing them would be if help @@ -189,27 +189,39 @@ License version 3 and version 2.1 along with this program. If not, see </dox:d> </property> + <property name="IconThemePath" type="as" access="read"> + <dox:d> + A list of directories that should be used for finding icons using + the icon naming spec. Idealy there should only be one for the icon + theme, but additional ones are often added by applications for + app specific icons. + </dox:d> + </property> + <!-- Functions --> <method name="GetLayout"> <dox:d> Provides the layout and propertiers that are attached to the entries that are in the layout. It only gives the items that are children - of the item that is specified in @parentId. It will return all of the - properties or specific ones depending of the value in @propertyNames. + of the item that is specified in @a parentId. It will return all of the + properties or specific ones depending of the value in @a propertyNames. The format is recursive, where the second 'v' is in the same format - as the original 'a(ia(sv)a(v))'. If the @recursive flag is set to - less than one then the second array will have zero entries. + as the original 'a(ia{sv}av)'. Its content depends on the value + of @a recursionDepth. </dox:d> <arg type="i" name="parentId" direction="in"> <dox:d>The ID of the parent node for the layout. For grabbing the layout from the root node use zero.</dox:d> </arg> - <arg type="i" name="recurse" direction="in"> + <arg type="i" name="recursionDepth" direction="in"> <dox:d> - The amount of levels of recursion to use. -1, as value would - deliver all the items under the @parentId. + The amount of levels of recursion to use. This affects the + content of the second variant array. + - -1: deliver all the items under the @a parentId. + - 0: no recursion, the array will be empty. + - n: array will contains items up to 'n' level depth. </dox:d> </arg> <arg type="as" name="propertyNames" direction="in" > @@ -224,13 +236,11 @@ License version 3 and version 2.1 along with this program. If not, see with layoutUpdated signals.</dox:d> </arg> <arg type="(ia{sv}av)" name="layout" direction="out"> - <dox:d>The layout as an XML string of IDs.</dox:d> + <dox:d>The layout, as a recursive structure.</dox:d> </arg> </method> <method name="GetGroupProperties"> - <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantList"/> - <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/> <dox:d> Returns the list of items which are children of @a parentId. </dox:d> @@ -327,7 +337,7 @@ License version 3 and version 2.1 along with this program. If not, see properties. </dox:d> <arg type="a(ia{sv})" name="updatedProps" direction="out" /> - <arg type="a(ias)" name="removedProps" direction="out" /> + <arg type="a(ias)" name="removedProps" direction="out" /> </signal> <signal name="LayoutUpdated"> <dox:d> diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c index c05ef38..9eaf9e5 100644 --- a/libdbusmenu-glib/defaults.c +++ b/libdbusmenu-glib/defaults.c @@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "config.h" #endif -#include <glib/gi18n.h> +#include <glib/gi18n-lib.h> #include "defaults.h" #include "menuitem.h" diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index 5202aa1..f7867e4 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -1146,13 +1146,14 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE); g_return_val_if_fail(property != NULL, FALSE); + g_return_val_if_fail(g_utf8_validate(property, -1, NULL), FALSE); DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi); GVariant * default_value = NULL; - if (value != NULL) { - const gchar * type = menuitem_get_type(mi); + const gchar * type = menuitem_get_type(mi); + if (value != NULL) { /* Check the expected type to see if we want to have a warning */ GVariantType * default_type = dbusmenu_defaults_default_get_type(priv->defaults, type, property); if (default_type != NULL) { @@ -1163,23 +1164,25 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro g_warning("Setting menuitem property '%s' with value of type '%s' when expecting '%s'", property, g_variant_get_type_string(value), g_variant_type_peek_string(default_type)); } } + } - /* Check the defaults database to see if we have a default - for this property. */ - default_value = dbusmenu_defaults_default_get(priv->defaults, type, property); - if (default_value != NULL) { - /* Now see if we're setting this to the same value as the - default. If we are then we just want to swallow this variant - and make the function behave like we're clearing it. */ - if (g_variant_equal(default_value, value)) { - g_variant_ref_sink(value); - g_variant_unref(value); - value = NULL; - } + /* Check the defaults database to see if we have a default + for this property. */ + default_value = dbusmenu_defaults_default_get(priv->defaults, type, property); + if (default_value != NULL && value != NULL) { + /* Now see if we're setting this to the same value as the + default. If we are then we just want to swallow this variant + and make the function behave like we're clearing it. */ + if (g_variant_equal(default_value, value)) { + g_variant_ref_sink(value); + g_variant_unref(value); + value = NULL; } } + gboolean replaced = FALSE; + gboolean remove = FALSE; gpointer currentval = g_hash_table_lookup(priv->properties, property); if (value != NULL) { @@ -1194,10 +1197,21 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro gchar * lprop = g_strdup(property); g_variant_ref_sink(value); - g_hash_table_replace(priv->properties, lprop, value); + /* Really important that this is _insert as that means the value + that we just created in the _strdup is free'd and not the one + currently in the hashtable. That could be the same as the one + being passed in and then the signal emit would be done with a + bad value */ + g_hash_table_insert(priv->properties, lprop, value); } else { if (currentval != NULL) { - g_hash_table_remove(priv->properties, property); + /* So the question you should be asking if you're paying attention + is "Why not just do the remove here?" It's a good question with + an interesting answer. Bascially it's the same reason as above, + in a couple cases the passed in properties is the value in the hash + table so we can avoid strdup'ing it by removing it (and thus free'ing + it) after the signal emition */ + remove = TRUE; replaced = TRUE; } } @@ -1218,6 +1232,10 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, property, signalval, TRUE); } + if (remove) { + g_hash_table_remove(priv->properties, property); + } + return TRUE; } @@ -1371,9 +1389,7 @@ dbusmenu_menuitem_property_remove (DbusmenuMenuitem * mi, const gchar * property g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); g_return_if_fail(property != NULL); - DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi); - - g_hash_table_remove(priv->properties, property); + dbusmenu_menuitem_property_set_variant(mi, property, NULL); return; } @@ -1670,11 +1686,22 @@ dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, GVari #endif DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi); + /* We need to keep a ref to the variant because the signal + handler will drop the floating ref and then we'll be up + a creek if we don't have our own later. */ + if (variant != NULL) { + g_variant_ref_sink(variant); + } + gboolean handled = FALSE; g_signal_emit(G_OBJECT(mi), signals[EVENT], g_quark_from_string(name), name, variant, timestamp, &handled); if (!handled && class->handle_event != NULL) { - return class->handle_event(mi, name, variant, timestamp); + class->handle_event(mi, name, variant, timestamp); + } + + if (variant != NULL) { + g_variant_unref(variant); } return; @@ -1742,13 +1769,8 @@ dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * prop return FALSE; } - currentval = dbusmenu_defaults_default_get(priv->defaults, menuitem_get_type(mi), property); - if (currentval != NULL) { - return TRUE; - } - - g_warn_if_reached(); - return FALSE; + /* If we haven't stored it locally, then it's the default */ + return TRUE; } /* Check to see if this menu item has been sent into the bus yet or diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 056d6cb..ca39ea3 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "config.h" #endif -#include <glib/gi18n.h> +#include <glib/gi18n-lib.h> #include <gio/gio.h> #include "menuitem-private.h" @@ -59,6 +59,7 @@ struct _DbusmenuServerPrivate DbusmenuTextDirection text_direction; DbusmenuStatus status; + GStrv icon_dirs; GArray * prop_array; guint property_idle; @@ -84,7 +85,8 @@ enum { PROP_ROOT_NODE, PROP_VERSION, PROP_TEXT_DIRECTION, - PROP_STATUS + PROP_STATUS, + PROP_ICON_THEME_DIRS }; /* Errors */ @@ -368,6 +370,7 @@ dbusmenu_server_init (DbusmenuServer *self) default_text_direction(self); priv->status = DBUSMENU_STATUS_NORMAL; + priv->icon_dirs = NULL; return; } @@ -425,6 +428,13 @@ dbusmenu_server_dispose (GObject *object) static void dbusmenu_server_finalize (GObject *object) { + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(object); + + if (priv->icon_dirs != NULL) { + g_strfreev(priv->icon_dirs); + priv->icon_dirs = NULL; + } + G_OBJECT_CLASS (dbusmenu_server_parent_class)->finalize (object); return; } @@ -499,9 +509,9 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) /* If the value has changed we need to signal that on DBus */ if (priv->text_direction != olddir && priv->bus != NULL && priv->dbusobject != NULL) { GVariantBuilder params; - g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); + g_variant_builder_init(¶ms, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); - GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("text-direction"), g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction))); + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("TextDirection"), g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction))); g_variant_builder_add_value(¶ms, g_variant_new_array(NULL, &dict, 1)); g_variant_builder_add_value(¶ms, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); GVariant * vparams = g_variant_builder_end(¶ms); @@ -523,9 +533,9 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) /* If the value has changed we need to signal that on DBus */ if (priv->status != instatus && priv->bus != NULL && priv->dbusobject != NULL) { GVariantBuilder params; - g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); + g_variant_builder_init(¶ms, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); - GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("status"), g_variant_new_string(dbusmenu_status_get_nick(instatus))); + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("Status"), g_variant_new_string(dbusmenu_status_get_nick(instatus))); g_variant_builder_add_value(¶ms, g_variant_new_array(NULL, &dict, 1)); g_variant_builder_add_value(¶ms, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); GVariant * vparams = g_variant_builder_end(¶ms); @@ -740,11 +750,21 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * g_return_val_if_fail(g_strcmp0(interface, DBUSMENU_INTERFACE) == 0, NULL); g_return_val_if_fail(g_strcmp0(path, priv->dbusobject) == 0, NULL); - if (g_strcmp0(property, "version") == 0) { + if (g_strcmp0(property, "Version") == 0) { return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER); - } else if (g_strcmp0(property, "text-direction") == 0) { + } else if (g_strcmp0(property, "TextDirection") == 0) { return g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction)); - } else if (g_strcmp0(property, "status") == 0) { + } else if (g_strcmp0(property, "IconThemePath") == 0) { + GVariant * dirs = NULL; + + if (priv->icon_dirs != NULL) { + dirs = g_variant_new_strv((const gchar * const *)priv->icon_dirs, -1); + } else { + dirs = g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0); + } + + return dirs; + } else if (g_strcmp0(property, "Status") == 0) { return g_variant_new_string(dbusmenu_status_get_nick(priv->status)); } else { g_warning("Unknown property '%s'", property); @@ -1180,7 +1200,11 @@ bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocatio GVariant * items = NULL; if (priv->root != NULL) { - items = dbusmenu_menuitem_build_variant(priv->root, props, recurse); + DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, parent); + + if (mi != NULL) { + items = dbusmenu_menuitem_build_variant(mi, props, recurse); + } } /* What happens if we don't have anything? */ @@ -1702,3 +1726,70 @@ dbusmenu_server_set_status (DbusmenuServer * server, DbusmenuStatus status) return; } + +/** + * dbusmenu_server_get_icon_paths: + * @server: The #DbusmenuServer to get the icon paths from + * + * Gets the stored and exported icon paths from the server. + * + * Return value: (transfer none): A NULL-terminated list of icon paths with + * memory managed by the server. Duplicate if you want + * to keep them. + */ +const GStrv +dbusmenu_server_get_icon_paths (DbusmenuServer * server) +{ + g_return_val_if_fail(DBUSMENU_IS_SERVER(server), NULL); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + return priv->icon_dirs; +} + +/** + dbusmenu_server_set_icon_paths: + @server: The #DbusmenuServer to set the icon paths on + + Sets the icon paths for the server. This will replace previously + set icon theme paths. +*/ +void +dbusmenu_server_set_icon_paths (DbusmenuServer * server, GStrv icon_paths) +{ + g_return_if_fail(DBUSMENU_IS_SERVER(server)); + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + + if (priv->icon_dirs != NULL) { + g_strfreev(priv->icon_dirs); + priv->icon_dirs = NULL; + } + + if (icon_paths != NULL) { + priv->icon_dirs = g_strdupv(icon_paths); + } + + if (priv->bus != NULL && priv->dbusobject != NULL) { + GVariantBuilder params; + g_variant_builder_init(¶ms, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); + GVariant * items = NULL; + if (priv->icon_dirs != NULL) { + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("IconThemePath"), g_variant_new_strv((const gchar * const *)priv->icon_dirs, -1)); + items = g_variant_new_array(NULL, &dict, 1); + } else { + items = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + } + g_variant_builder_add_value(¶ms, items); + g_variant_builder_add_value(¶ms, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); + GVariant * vparams = g_variant_builder_end(¶ms); + + g_dbus_connection_emit_signal(priv->bus, + NULL, + priv->dbusobject, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + vparams, + NULL); + } + + return; +} diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h index 80b7abb..5feb09b 100644 --- a/libdbusmenu-glib/server.h +++ b/libdbusmenu-glib/server.h @@ -167,6 +167,9 @@ void dbusmenu_server_set_text_direction (DbusmenuServer * DbusmenuStatus dbusmenu_server_get_status (DbusmenuServer * server); void dbusmenu_server_set_status (DbusmenuServer * server, DbusmenuStatus status); +const GStrv dbusmenu_server_get_icon_paths (DbusmenuServer * server); +void dbusmenu_server_set_icon_paths (DbusmenuServer * server, + GStrv icon_paths); /** SECTION:server |