aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore4
-rw-r--r--Makefile.am.enum45
-rw-r--r--configure.ac2
-rw-r--r--docs/libdbusmenu-glib/reference/Makefile.am18
-rw-r--r--docs/libdbusmenu-glib/reference/libdbusmenu-glib-docs.sgml5
-rw-r--r--docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt86
-rw-r--r--docs/libdbusmenu-gtk/reference/Makefile.am11
-rw-r--r--docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml9
-rw-r--r--docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-sections.txt77
-rw-r--r--libdbusmenu-glib/Makefile.am23
-rw-r--r--libdbusmenu-glib/client-marshal.list1
-rw-r--r--libdbusmenu-glib/client-menuitem.c5
-rw-r--r--libdbusmenu-glib/client-menuitem.h12
-rw-r--r--libdbusmenu-glib/client-private.h48
-rw-r--r--libdbusmenu-glib/client.c183
-rw-r--r--libdbusmenu-glib/client.h89
-rw-r--r--libdbusmenu-glib/dbus-menu.xml18
-rw-r--r--libdbusmenu-glib/defaults.c8
-rw-r--r--libdbusmenu-glib/defaults.h4
-rw-r--r--libdbusmenu-glib/enum-types.c.in116
-rw-r--r--libdbusmenu-glib/enum-types.h.in62
-rw-r--r--libdbusmenu-glib/menuitem-marshal.list1
-rw-r--r--libdbusmenu-glib/menuitem-private.h1
-rw-r--r--libdbusmenu-glib/menuitem-proxy.h14
-rw-r--r--libdbusmenu-glib/menuitem.c225
-rw-r--r--libdbusmenu-glib/menuitem.h209
-rw-r--r--libdbusmenu-glib/server.c260
-rw-r--r--libdbusmenu-glib/server.h72
-rw-r--r--libdbusmenu-glib/types.h76
-rw-r--r--libdbusmenu-gtk/client.h42
-rw-r--r--libdbusmenu-gtk/genericmenuitem.c2
-rw-r--r--libdbusmenu-gtk/genericmenuitem.h4
-rw-r--r--libdbusmenu-gtk/menu.c2
-rw-r--r--libdbusmenu-gtk/menu.h33
-rw-r--r--libdbusmenu-gtk/menuitem.h11
-rw-r--r--libdbusmenu-gtk/parser.c81
-rw-r--r--libdbusmenu-gtk/parser.h14
-rw-r--r--libdbusmenu-gtk/serializablemenuitem.h18
-rw-r--r--po/POTFILES.in1
39 files changed, 1702 insertions, 190 deletions
diff --git a/.bzrignore b/.bzrignore
index c5cc6ff..837b948 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -228,3 +228,7 @@ test-gtk-parser
test-gtk-parser-test
test-gtk-parser.xml
libdbusmenu-glib/libdbusmenu_glib_la-defaults.lo
+enum-types.c
+enum-types.h
+libdbusmenu_glib_la-enum-types.lo
+stamp-enum-types
diff --git a/Makefile.am.enum b/Makefile.am.enum
new file mode 100644
index 0000000..0503de0
--- /dev/null
+++ b/Makefile.am.enum
@@ -0,0 +1,45 @@
+# Rules for generating enumeration types using glib-mkenums
+#
+# Define:
+# glib_enum_h = header template file
+# glib_enum_c = source template file
+# glib_enum_headers = list of headers to parse
+#
+# before including Makefile.am.enums. You will also need to have
+# the following targets already defined:
+#
+# CLEANFILES
+# DISTCLEANFILES
+# BUILT_SOURCES
+# EXTRA_DIST
+#
+# Author: Emmanuele Bassi <ebassi@linux.intel.com>
+
+enum_tmpl_h=$(glib_enum_h:.h=.h.in)
+enum_tmpl_c=$(glib_enum_c:.c=.c.in)
+
+CLEANFILES += stamp-enum-types
+DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c)
+BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c)
+EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c)
+
+stamp-enum-types: $(glib_enum_headers)
+ $(QUIET_GEN)mkdir -p `dirname $(builddir)/$(glib_enum_h)`
+ $(QUIET_GEN)$(GLIB_MKENUMS) \
+ --template $(srcdir)/$(enum_tmpl_h) \
+ $(glib_enum_headers) > xgen-eh \
+ && (cmp -s xgen-eh $(builddir)/$(glib_enum_h) || cp -f xgen-eh $(builddir)/$(glib_enum_h)) \
+ && rm -f xgen-eh \
+ && echo timestamp > $(@F)
+
+$(glib_enum_h): stamp-enum-types
+ @true
+
+$(glib_enum_c): $(glib_enum_h)
+ $(QUIET_GEN)mkdir -p `dirname $(builddir)/$(glib_enum_c)`
+ $(QUIET_GEN)$(GLIB_MKENUMS) \
+ --template $(srcdir)/$(enum_tmpl_c) \
+ $(glib_enum_headers) > xgen-ec \
+ && cp -f xgen-ec $(builddir)/$(glib_enum_c) \
+ && rm -f xgen-ec
+
diff --git a/configure.ac b/configure.ac
index a1af560..7f53d3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,6 +21,8 @@ AC_CONFIG_MACRO_DIR([m4])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums])
+
AC_ARG_ENABLE([deprecations],
[AS_HELP_STRING([--enable-deprecations],
[allow deprecated API usage @<:@default=yes@:>@])],
diff --git a/docs/libdbusmenu-glib/reference/Makefile.am b/docs/libdbusmenu-glib/reference/Makefile.am
index e8a3610..2af5ec3 100644
--- a/docs/libdbusmenu-glib/reference/Makefile.am
+++ b/docs/libdbusmenu-glib/reference/Makefile.am
@@ -48,11 +48,13 @@ CFILE_GLOB=$(top_srcdir)/libdbusmenu-glib/*.c
# Header files to ignore when scanning.
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES= \
+ dbus-menu-clean.xml.h \
+ client-menuitem.h \
+ client-private.h \
+ defaults.h \
menuitem-marshal.h \
server-marshal.h \
- menuitem-private.h \
- dbusmenu-client.h \
- dbusmenu-server.h
+ menuitem-private.h
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
@@ -88,5 +90,13 @@ EXTRA_DIST += version.xml.in
#DISTCLEANFILES +=
# Comment this out if you want your docs-status tested during 'make check'
-#TESTS = $(GTKDOC_CHECK)
+TESTS = gtkdoc-in-srcdir
+
+gtkdoc-in-srcdir: Makefile.am
+ @echo "#!/bin/sh" > $@
+ @echo "cd \"$(srcdir)\"" >> $@
+ @echo "$(GTKDOC_CHECK)" >> $@
+ @chmod +x $@
+
+DISTCLEANFILES = gtkdoc-in-srcdir
diff --git a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-docs.sgml b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-docs.sgml
index ecc25a3..53a0ceb 100644
--- a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-docs.sgml
+++ b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-docs.sgml
@@ -18,6 +18,7 @@
<xi:include href="xml/client-menuitem.xml"/>
<xi:include href="xml/dbusmenu-client.xml"/>
<xi:include href="xml/dbusmenu-server.xml"/>
+ <xi:include href="xml/types.xml"/>
</chapter>
<chapter id="object-tree">
@@ -28,6 +29,10 @@
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-deprecated">
+ <title>Deprecated API Index</title>
+ <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
diff --git a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
index 0186049..b1e2d8c 100644
--- a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
+++ b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
@@ -4,27 +4,36 @@
DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED
DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED
DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM
+DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT
+DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE
+DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED
DBUSMENU_CLIENT_PROP_DBUS_NAME
DBUSMENU_CLIENT_PROP_DBUS_OBJECT
+DBUSMENU_CLIENT_PROP_STATUS
+DBUSMENU_CLIENT_PROP_TEXT_DIRECTION
DBUSMENU_CLIENT_TYPES_DEFAULT
DBUSMENU_CLIENT_TYPES_SEPARATOR
DBUSMENU_CLIENT_TYPES_IMAGE
DbusmenuClient
DbusmenuClientClass
DbusmenuClientTypeHandler
+DbusmenuClientTypeDestroyHandler
dbusmenu_client_new
dbusmenu_client_get_root
+dbusmenu_client_get_status
+dbusmenu_client_get_text_direction
dbusmenu_client_add_type_handler
-dbusmenu_client_send_event
-dbusmenu_client_send_about_to_show
+dbusmenu_client_add_type_handler_full
<SUBSECTION Standard>
DBUSMENU_CLIENT
DBUSMENU_IS_CLIENT
DBUSMENU_TYPE_CLIENT
-dbusmenu_client_get_type
DBUSMENU_CLIENT_CLASS
DBUSMENU_IS_CLIENT_CLASS
DBUSMENU_CLIENT_GET_CLASS
+<SUBSECTION Private>
+DbusmenuClientPrivate
+dbusmenu_client_get_type
</SECTION>
<SECTION>
@@ -35,8 +44,11 @@ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED
DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED
DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED
DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED
+DBUSMENU_MENUITEM_SIGNAL_EVENT
DBUSMENU_MENUITEM_SIGNAL_REALIZED
DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID
+DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW
+DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER
DBUSMENU_MENUITEM_PROP_TYPE
DBUSMENU_MENUITEM_PROP_VISIBLE
DBUSMENU_MENUITEM_PROP_ENABLED
@@ -46,6 +58,7 @@ DBUSMENU_MENUITEM_PROP_ICON_DATA
DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE
DBUSMENU_MENUITEM_PROP_TOGGLE_STATE
DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY
+DBUSMENU_MENUITEM_PROP_SHORTCUT
DBUSMENU_MENUITEM_TOGGLE_CHECK
DBUSMENU_MENUITEM_TOGGLE_RADIO
DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED
@@ -53,9 +66,13 @@ DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED
DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN
DBUSMENU_MENUITEM_ICON_NAME_BLANK
DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU
+DBUSMENU_MENUITEM_SHORTCUT_ALT
+DBUSMENU_MENUITEM_SHORTCUT_CONTROL
+DBUSMENU_MENUITEM_SHORTCUT_SHIFT
+DBUSMENU_MENUITEM_SHORTCUT_SUPER
DbusmenuMenuitem
dbusmenu_menuitem_about_to_show_cb
-dbusmenu_menuitem_buildxml_slot_t
+dbusmenu_menuitem_buildvariant_slot_t
DbusmenuMenuitemClass
dbusmenu_menuitem_new
dbusmenu_menuitem_new_with_id
@@ -72,13 +89,13 @@ dbusmenu_menuitem_child_reorder
dbusmenu_menuitem_child_find
dbusmenu_menuitem_find_id
dbusmenu_menuitem_property_set
-dbusmenu_menuitem_property_set_value
dbusmenu_menuitem_property_set_bool
dbusmenu_menuitem_property_set_int
+dbusmenu_menuitem_property_set_variant
dbusmenu_menuitem_property_get
-dbusmenu_menuitem_property_get_value
dbusmenu_menuitem_property_get_bool
dbusmenu_menuitem_property_get_int
+dbusmenu_menuitem_property_get_variant
dbusmenu_menuitem_property_exist
dbusmenu_menuitem_properties_list
dbusmenu_menuitem_properties_copy
@@ -88,14 +105,20 @@ dbusmenu_menuitem_get_root
dbusmenu_menuitem_foreach
dbusmenu_menuitem_handle_event
dbusmenu_menuitem_send_about_to_show
+dbusmenu_menuitem_show_to_user
+dbusmenu_menuitem_get_parent
+dbusmenu_menuitem_set_parent
+dbusmenu_menuitem_unparent
<SUBSECTION Standard>
DBUSMENU_MENUITEM
DBUSMENU_IS_MENUITEM
DBUSMENU_TYPE_MENUITEM
-dbusmenu_menuitem_get_type
DBUSMENU_MENUITEM_CLASS
DBUSMENU_IS_MENUITEM_CLASS
DBUSMENU_MENUITEM_GET_CLASS
+<SUBSECTION Private>
+DbusmenuMenuitemPrivate
+dbusmenu_menuitem_get_type
</SECTION>
<SECTION>
@@ -105,37 +128,30 @@ DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE
DBUSMENU_SERVER_SIGNAL_ID_UPDATE
DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED
DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE
+DBUSMENU_SERVER_SIGNAL_ITEM_ACTIVATION
DBUSMENU_SERVER_PROP_DBUS_OBJECT
DBUSMENU_SERVER_PROP_ROOT_NODE
+DBUSMENU_SERVER_PROP_STATUS
+DBUSMENU_SERVER_PROP_TEXT_DIRECTION
DBUSMENU_SERVER_PROP_VERSION
DbusmenuServer
DbusmenuServerClass
dbusmenu_server_new
+dbusmenu_server_get_status
+dbusmenu_server_get_text_direction
dbusmenu_server_set_root
+dbusmenu_server_set_status
+dbusmenu_server_set_text_direction
<SUBSECTION Standard>
DBUSMENU_SERVER
DBUSMENU_IS_SERVER
DBUSMENU_TYPE_SERVER
-dbusmenu_server_get_type
DBUSMENU_SERVER_CLASS
DBUSMENU_IS_SERVER_CLASS
DBUSMENU_SERVER_GET_CLASS
-</SECTION>
-
-<SECTION>
-<FILE>client-menuitem</FILE>
-<TITLE>DbusmenuClientMenuitem</TITLE>
-DBUSMENU_CLIENT_MENUITEM_TYPE
-DbusmenuClientMenuitem
-DbusmenuClientMenuitemClass
-dbusmenu_client_menuitem_new
-<SUBSECTION Standard>
-DBUSMENU_CLIENT_MENUITEM
-DBUSMENU_IS_CLIENT_MENUITEM
-dbusmenu_client_menuitem_get_type
-DBUSMENU_CLIENT_MENUITEM_CLASS
-DBUSMENU_IS_CLIENT_MENUITEM_CLASS
-DBUSMENU_CLIENT_MENUITEM_GET_CLASS
+<SUBSECTION Private>
+DbusmenuServerPrivate
+dbusmenu_server_get_type
</SECTION>
<SECTION>
@@ -149,9 +165,29 @@ dbusmenu_menuitem_proxy_get_wrapped
DBUSMENU_MENUITEM_PROXY
DBUSMENU_IS_MENUITEM_PROXY
DBUSMENU_TYPE_MENUITEM_PROXY
-dbusmenu_menuitem_proxy_get_type
DBUSMENU_MENUITEM_PROXY_CLASS
DBUSMENU_IS_MENUITEM_PROXY_CLASS
DBUSMENU_MENUITEM_PROXY_GET_CLASS
+<SUBSECTION Private>
+DbusmenuMenuitemProxyPrivate
+dbusmenu_menuitem_proxy_get_type
+</SECTION>
+
+<SECTION>
+<FILE>types</FILE>
+<TITLE>Types</TITLE>
+DBUSMENU_TYPE_STATUS
+DBUSMENU_TYPE_TEXT_DIRECTION
+DbusmenuStatus
+DbusmenuTextDirection
+dbusmenu_status_get_nick
+dbusmenu_status_get_type
+dbusmenu_status_get_value_from_nick
+dbusmenu_text_direction_get_nick
+dbusmenu_text_direction_get_type
+dbusmenu_text_direction_get_value_from_nick
+<SUBSECTION Private>
+DbusmenuServerPrivate
+dbusmenu_server_get_type
</SECTION>
diff --git a/docs/libdbusmenu-gtk/reference/Makefile.am b/docs/libdbusmenu-gtk/reference/Makefile.am
index 191d68e..06d0009 100644
--- a/docs/libdbusmenu-gtk/reference/Makefile.am
+++ b/docs/libdbusmenu-gtk/reference/Makefile.am
@@ -16,7 +16,7 @@ AUTOMAKE_OPTIONS = 1.6
# of using the various options.
# The name of the module, e.g. 'glib'.
-DOC_MODULE=libdbusmenu-gtk$(VER)
+DOC_MODULE=libdbusmenu-gtk
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
@@ -90,5 +90,12 @@ EXTRA_DIST += version.xml.in
#DISTCLEANFILES +=
# Comment this out if you want your docs-status tested during 'make check'
-#TESTS = $(GTKDOC_CHECK)
+TESTS = gtkdoc-in-srcdir
+gtkdoc-in-srcdir: Makefile.am
+ @echo "#!/bin/sh" > $@
+ @echo "cd \"$(srcdir)\"" >> $@
+ @echo "$(GTKDOC_CHECK)" >> $@
+ @chmod +x $@
+
+DISTCLEANFILES = gtkdoc-in-srcdir
diff --git a/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml b/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml
index ec6b82f..e9020de 100644
--- a/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml
+++ b/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml
@@ -11,9 +11,10 @@
<chapter>
<title>API</title>
- <xi:include href="xml/menu.xml"/>
- <xi:include href="xml/client.xml"/>
+ <xi:include href="xml/menu.xml"/>
<xi:include href="xml/menuitem.xml"/>
+ <xi:include href="xml/client.xml"/>
+ <xi:include href="xml/parser.xml"/>
<xi:include href="xml/serializablemenuitem.xml"/>
</chapter>
@@ -25,6 +26,10 @@
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-deprecated">
+ <title>Deprecated API Index</title>
+ <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
diff --git a/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-sections.txt b/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-sections.txt
new file mode 100644
index 0000000..77101f7
--- /dev/null
+++ b/docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-sections.txt
@@ -0,0 +1,77 @@
+<SECTION>
+<FILE>client</FILE>
+<TITLE>DbusmenuGtkClient</TITLE>
+DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED
+DbusmenuGtkClient
+DbusmenuGtkClientClass
+dbusmenu_gtkclient_new
+dbusmenu_gtkclient_menuitem_get
+dbusmenu_gtkclient_menuitem_get_submenu
+dbusmenu_gtkclient_set_accel_group
+dbusmenu_gtkclient_get_accel_group
+dbusmenu_gtkclient_newitem_base
+<SUBSECTION Standard>
+DBUSMENU_GTKCLIENT
+DBUSMENU_IS_GTKCLIENT
+DBUSMENU_GTKCLIENT_CLASS
+DBUSMENU_IS_GTKCLIENT_CLASS
+DBUSMENU_GTKCLIENT_GET_CLASS
+<SUBSECTION Private>
+DBUSMENU_GTKCLIENT_TYPE
+dbusmenu_gtkclient_get_type
+DbusmenuGtkClientPrivate
+</SECTION>
+
+<SECTION>
+<FILE>serializablemenuitem</FILE>
+<TITLE>DbusmenuGtkSerializableMenuItem</TITLE>
+DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM
+DbusmenuGtkSerializableMenuItemClass
+dbusmenu_gtk_serializable_menu_item_build_menuitem
+dbusmenu_gtk_serializable_menu_item_register_to_client
+dbusmenu_gtk_serializable_menu_item_set_menuitem
+<SUBSECTION Standard>
+DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM
+DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM
+DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_CLASS
+DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM_CLASS
+DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS
+<SUBSECTION Private>
+DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM
+dbusmenu_gtk_serializable_menu_item_get_type
+DbusmenuGtkSerializableMenuItemPrivate
+</SECTION>
+
+<SECTION>
+<FILE>menu</FILE>
+<TITLE>DbusmenuGtkMenu</TITLE>
+DbusmenuGtkMenuClass
+dbusmenu_gtkmenu_new
+dbusmenu_gtkmenu_get_client
+<SUBSECTION Standard>
+DBUSMENU_GTKMENU
+DBUSMENU_IS_GTKMENU
+DBUSMENU_GTKMENU_CLASS
+DBUSMENU_IS_GTKMENU_CLASS
+DBUSMENU_GTKMENU_GET_CLASS
+<SUBSECTION Private>
+dbusmenu_gtkmenu_get_type
+DBUSMENU_GTKMENU_TYPE
+DbusmenuGtkMenuPrivate
+</SECTION>
+
+<SECTION>
+<FILE>menuitem</FILE>
+dbusmenu_menuitem_property_set_image
+dbusmenu_menuitem_property_get_image
+dbusmenu_menuitem_property_set_shortcut
+dbusmenu_menuitem_property_set_shortcut_string
+dbusmenu_menuitem_property_set_shortcut_menuitem
+dbusmenu_menuitem_property_get_shortcut
+</SECTION>
+
+<SECTION>
+<FILE>parser</FILE>
+dbusmenu_gtk_parse_menu_structure
+</SECTION>
+
diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am
index 5ddbeb8..8b523aa 100644
--- a/libdbusmenu-glib/Makefile.am
+++ b/libdbusmenu-glib/Makefile.am
@@ -1,6 +1,7 @@
-CLEANFILES =
-
+BUILT_SOURCES =
+CLEANFILES =
+DISTCLEANFILES =
EXTRA_DIST = \
clean-namespaces.xslt \
dbusmenu-glib-0.4.pc.in \
@@ -9,6 +10,8 @@ EXTRA_DIST = \
menuitem-marshal.list \
server-marshal.list
+include $(top_srcdir)/Makefile.am.enum
+
lib_LTLIBRARIES = \
libdbusmenu-glib.la
@@ -19,13 +22,16 @@ libdbusmenu_glibinclude_HEADERS = \
menuitem.h \
menuitem-proxy.h \
server.h \
- client.h
+ client.h \
+ types.h
libdbusmenu_glib_la_SOURCES = \
dbus-menu-clean.xml.h \
dbus-menu-clean.xml.c \
defaults.h \
defaults.c \
+ enum-types.h \
+ enum-types.c \
menuitem.h \
menuitem.c \
menuitem-marshal.h \
@@ -41,6 +47,7 @@ libdbusmenu_glib_la_SOURCES = \
client-marshal.c \
client-menuitem.h \
client-menuitem.c \
+ client-private.h \
client.h \
client.c
@@ -58,6 +65,14 @@ libdbusmenu_glib_la_LIBADD = \
pkgconfig_DATA = dbusmenu-glib-0.4.pc
pkgconfigdir = $(libdir)/pkgconfig
+glib_enum_h = enum-types.h
+glib_enum_c = enum-types.c
+glib_enum_headers = $(addprefix $(srcdir)/, $(libdbusmenu_glibinclude_HEADERS))
+
+DISTCLEANFILES += \
+ enum-types.c \
+ enum-types.h
+
%.xml.h: %.xml
echo "extern const char * $(subst -,_,$(subst .,_,$(basename $(notdir $@))));" > $@
@@ -71,7 +86,7 @@ dbus-menu-clean.xml: dbus-menu.xml
CLEANFILES += dbus-menu-clean.xml
-BUILT_SOURCES = \
+BUILT_SOURCES += \
dbus-menu-clean.xml.c \
dbus-menu-clean.xml.h \
client-marshal.h \
diff --git a/libdbusmenu-glib/client-marshal.list b/libdbusmenu-glib/client-marshal.list
index 866dfa8..96f9302 100644
--- a/libdbusmenu-glib/client-marshal.list
+++ b/libdbusmenu-glib/client-marshal.list
@@ -1,2 +1,3 @@
VOID: OBJECT, UINT
VOID: OBJECT, STRING, VARIANT, UINT, POINTER
+VOID: ENUM
diff --git a/libdbusmenu-glib/client-menuitem.c b/libdbusmenu-glib/client-menuitem.c
index 0f14b85..60f8637 100644
--- a/libdbusmenu-glib/client-menuitem.c
+++ b/libdbusmenu-glib/client-menuitem.c
@@ -30,6 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see
#endif
#include "client-menuitem.h"
+#include "client-private.h"
typedef struct _DbusmenuClientMenuitemPrivate DbusmenuClientMenuitemPrivate;
@@ -39,7 +40,7 @@ struct _DbusmenuClientMenuitemPrivate
};
#define DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(o) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemPrivate))
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemPrivate))
static void dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass);
static void dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self);
@@ -94,7 +95,7 @@ dbusmenu_client_menuitem_finalize (GObject *object)
DbusmenuClientMenuitem *
dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client)
{
- DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_CLIENT_MENUITEM_TYPE, "id", id, NULL);
+ DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_TYPE_CLIENT_MENUITEM, "id", id, NULL);
DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
priv->client = client;
return mi;
diff --git a/libdbusmenu-glib/client-menuitem.h b/libdbusmenu-glib/client-menuitem.h
index ef61213..a89cb11 100644
--- a/libdbusmenu-glib/client-menuitem.h
+++ b/libdbusmenu-glib/client-menuitem.h
@@ -35,12 +35,12 @@ License version 3 and version 2.1 along with this program. If not, see
G_BEGIN_DECLS
-#define DBUSMENU_CLIENT_MENUITEM_TYPE (dbusmenu_client_menuitem_get_type ())
-#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitem))
-#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
-#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE))
-#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE))
-#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
+#define DBUSMENU_TYPE_CLIENT_MENUITEM (dbusmenu_client_menuitem_get_type ())
+#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitem))
+#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemClass))
+#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM))
+#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_CLIENT_MENUITEM))
+#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemClass))
typedef struct _DbusmenuClientMenuitem DbusmenuClientMenuitem;
typedef struct _DbusmenuClientMenuitemClass DbusmenuClientMenuitemClass;
diff --git a/libdbusmenu-glib/client-private.h b/libdbusmenu-glib/client-private.h
new file mode 100644
index 0000000..f6df372
--- /dev/null
+++ b/libdbusmenu-glib/client-private.h
@@ -0,0 +1,48 @@
+/*
+A library to communicate a menu object set accross DBus and
+track updates and maintain consistency.
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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_CLIENT_PRIVATE_H__
+#define __DBUSMENU_CLIENT_PRIVATE_H__
+
+#include "client.h"
+
+G_BEGIN_DECLS
+
+void dbusmenu_client_send_event (DbusmenuClient * client,
+ gint id,
+ const gchar * name,
+ GVariant * variant,
+ guint timestamp);
+void dbusmenu_client_send_about_to_show(DbusmenuClient * client,
+ gint id,
+ void (*cb) (gpointer user_data),
+ gpointer cb_data);
+
+G_END_DECLS
+
+#endif
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 0848294..d368a0e 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -33,12 +33,14 @@ License version 3 and version 2.1 along with this program. If not, see
#include <gio/gio.h>
#include "client.h"
+#include "client-private.h"
#include "menuitem.h"
#include "menuitem-private.h"
#include "client-menuitem.h"
#include "server-marshal.h"
#include "client-marshal.h"
#include "dbus-menu-clean.xml.h"
+#include "enum-types.h"
/* How many property requests should we queue before
sending the message on dbus */
@@ -48,7 +50,9 @@ License version 3 and version 2.1 along with this program. If not, see
enum {
PROP_0,
PROP_DBUSOBJECT,
- PROP_DBUSNAME
+ PROP_DBUSNAME,
+ PROP_STATUS,
+ PROP_TEXT_DIRECTION
};
/* Signals */
@@ -79,6 +83,7 @@ struct _DbusmenuClientPrivate
GCancellable * menuproxy_cancel;
GCancellable * layoutcall;
+ GVariant * layout_props;
gint current_revision;
gint my_revision;
@@ -90,6 +95,9 @@ struct _DbusmenuClientPrivate
GArray * delayed_property_list;
GArray * delayed_property_listeners;
gint delayed_idle;
+
+ DbusmenuTextDirection text_direction;
+ DbusmenuStatus status;
};
typedef struct _newItemPropData newItemPropData;
@@ -157,6 +165,7 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gcha
static GQuark error_domain (void);
static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client);
static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv invalidated, gpointer user_data);
static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data);
static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data);
static void type_handler_destroy (gpointer user_data);
@@ -274,6 +283,16 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass)
"Name of the DBus client we're connecting to.",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_STATUS,
+ g_param_spec_enum(DBUSMENU_CLIENT_PROP_STATUS, "Status of viewing the menus",
+ "Whether the menus should be given special visuals",
+ DBUSMENU_TYPE_STATUS, DBUSMENU_STATUS_NORMAL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_TEXT_DIRECTION,
+ g_param_spec_enum(DBUSMENU_CLIENT_PROP_TEXT_DIRECTION, "Direction text values have",
+ "Signals which direction the default text direction is for the menus",
+ DBUSMENU_TYPE_TEXT_DIRECTION, DBUSMENU_TEXT_DIRECTION_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
if (dbusmenu_node_info == NULL) {
GError * error = NULL;
@@ -316,6 +335,15 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->layoutcall = NULL;
+ gchar * layout_props[5];
+ layout_props[0] = DBUSMENU_MENUITEM_PROP_TYPE;
+ layout_props[1] = DBUSMENU_MENUITEM_PROP_LABEL;
+ layout_props[2] = DBUSMENU_MENUITEM_PROP_VISIBLE;
+ layout_props[3] = DBUSMENU_MENUITEM_PROP_ENABLED;
+ layout_props[4] = NULL;
+ priv->layout_props = g_variant_new_strv((const gchar * const *)layout_props, 4);
+ g_variant_ref_sink(priv->layout_props);
+
priv->current_revision = 0;
priv->my_revision = 0;
@@ -328,6 +356,9 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *));
priv->delayed_property_listeners = g_array_new(FALSE, FALSE, sizeof(properties_listener_t));
+ priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE;
+ priv->status = DBUSMENU_STATUS_NORMAL;
+
return;
}
@@ -380,6 +411,11 @@ dbusmenu_client_dispose (GObject *object)
priv->layoutcall = NULL;
}
+ if (priv->layout_props != NULL) {
+ g_variant_unref(priv->layout_props);
+ priv->layout_props = NULL;
+ }
+
/* Bring down the menu proxy, ensure we're not
looking for one at the same time. */
if (priv->menuproxy_cancel != NULL) {
@@ -472,6 +508,12 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
case PROP_DBUSOBJECT:
g_value_set_string(value, priv->dbus_object);
break;
+ case PROP_STATUS:
+ g_value_set_enum(value, priv->status);
+ break;
+ case PROP_TEXT_DIRECTION:
+ g_value_set_enum(value, priv->text_direction);
+ break;
default:
g_warning("Unknown property %d.", id);
return;
@@ -983,6 +1025,19 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
priv->menuproxy_cancel = NULL;
}
+ /* Check the text direction if available */
+ GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "text-direction");
+ if (textdir != NULL) {
+ GVariant * str = textdir;
+ if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
+ str = g_variant_get_variant(str);
+ }
+
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+
+ g_variant_unref(textdir);
+ }
+
/* If we get here, we don't need the DBus proxy */
if (priv->dbusproxy != 0) {
g_bus_unwatch_name(priv->dbusproxy);
@@ -991,6 +1046,7 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client);
g_signal_connect(priv->menuproxy, "notify::g-name-owner", G_CALLBACK(menuproxy_name_changed_cb), client);
+ g_signal_connect(priv->menuproxy, "g-properties-changed", G_CALLBACK(menuproxy_prop_changed_cb), client);
gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy);
if (name_owner != NULL) {
@@ -1001,6 +1057,63 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
return;
}
+/* Handle the properites changing */
+static void
+menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv invalidated, gpointer user_data)
+{
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data);
+ DbusmenuTextDirection olddir = priv->text_direction;
+ DbusmenuStatus oldstatus = priv->status;
+
+ /* Invalidate first */
+ gchar * invalid;
+ gint i = 0;
+ for (invalid = invalidated[i]; invalid != NULL; invalid = invalidated[++i]) {
+ if (g_strcmp0(invalid, "text-direction") == 0) {
+ priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE;
+ }
+ if (g_strcmp0(invalid, "status") == 0) {
+ priv->status = DBUSMENU_STATUS_NORMAL;
+ }
+ }
+
+ /* Check updates */
+ GVariantIter iters;
+ 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) {
+ GVariant * str = value;
+ if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
+ str = g_variant_get_variant(str);
+ }
+
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+ }
+ 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);
+ }
+
+ priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));
+ }
+
+ g_variant_unref(value);
+ g_free(key);
+ }
+
+ if (olddir != priv->text_direction) {
+ g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_TEXT_DIRECTION);
+ }
+
+ if (oldstatus != priv->status) {
+ g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS);
+ }
+
+ return;
+}
+
/* Handle the case where we change owners */
static void
menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data)
@@ -1473,6 +1586,33 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
parse_layout_update(childmi, client);
}
+ /* Apply known properties sent in the structure to the
+ menu item. Sometimes they may just be copies */
+ if (childmi != NULL) {
+ GVariantIter iter;
+ gchar * prop;
+ GVariant * value;
+
+ /* Set the type first as it can manage the behavior of
+ all other properties. */
+ g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
+ while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
+ if (g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TYPE) == 0) {
+ dbusmenu_menuitem_property_set_variant(childmi, prop, value);
+ }
+ g_free(prop);
+ g_variant_unref(value);
+ }
+
+ /* Now go through and do all the properties. */
+ g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
+ while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
+ dbusmenu_menuitem_property_set_variant(childmi, prop, value);
+ g_free(prop);
+ g_variant_unref(value);
+ }
+ }
+
position++;
}
@@ -1662,7 +1802,7 @@ update_layout (DbusmenuClient * client)
g_variant_builder_add_value(&tupleb, g_variant_new_int32(0)); // root
g_variant_builder_add_value(&tupleb, g_variant_new_int32(-1)); // recurse
- g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); // props
+ g_variant_builder_add_value(&tupleb, priv->layout_props); // props
GVariant * args = g_variant_builder_end(&tupleb);
// g_debug("Args (type: %s): %s", g_variant_get_type_string(args), g_variant_print(args, TRUE));
@@ -1834,3 +1974,42 @@ dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * ty
return TRUE;
}
+/**
+ dbusmenu_client_get_text_direction:
+ @client: #DbusmenuClient to check the text direction on
+
+ Gets the text direction that the server is exporting. If
+ the server is not exporting a direction then the value
+ #DBUSMENU_TEXT_DIRECTION_NONE will be returned.
+
+ Return value: Text direction being exported.
+*/
+DbusmenuTextDirection
+dbusmenu_client_get_text_direction (DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), DBUSMENU_TEXT_DIRECTION_NONE);
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
+ return priv->text_direction;
+}
+
+/**
+ dbusmenu_client_get_status:
+ @client: #DbusmenuClient to check the status on
+
+ Gets the recommended current status that the server
+ is exporting for the menus. In situtations where the
+ value is #DBUSMENU_STATUS_NOTICE it is recommended that
+ the client show the menus to the user an a more noticible
+ way.
+
+ Return value: Status being exported.
+*/
+DbusmenuStatus
+dbusmenu_client_get_status (DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), DBUSMENU_STATUS_NORMAL);
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
+ return priv->status;
+}
+
+
diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h
index 79c0ee2..28d4dd3 100644
--- a/libdbusmenu-glib/client.h
+++ b/libdbusmenu-glib/client.h
@@ -33,6 +33,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include <glib-object.h>
#include "menuitem.h"
+#include "types.h"
G_BEGIN_DECLS
@@ -43,17 +44,89 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_CLIENT))
#define DBUSMENU_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_CLIENT, DbusmenuClientClass))
+/**
+ * DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED:
+ *
+ * String to attach to signal #DbusmenuClient::layout-updated
+ */
#define DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED "layout-updated"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED:
+ *
+ * String to attach to signal #DbusmenuClient::root-changed
+ */
#define DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED "root-changed"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM:
+ *
+ * String to attach to signal #DbusmenuClient::new-menuitem
+ */
#define DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM "new-menuitem"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE:
+ *
+ * String to attach to signal #DbusmenuClient::item-activate
+ */
#define DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE "item-activate"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT:
+ *
+ * String to attach to signal #DbusmenuClient::event-result
+ */
#define DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT "event-result"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED:
+ *
+ * String to attach to signal #DbusmenuClient::text-direction-changed
+ */
+#define DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED "text-direction-changed"
+/**
+ * DBUSMENU_CLIENT_PROP_DBUS_NAME:
+ *
+ * String to access property #DbusmenuClient:dbus-name
+ */
#define DBUSMENU_CLIENT_PROP_DBUS_NAME "dbus-name"
+/**
+ * DBUSMENU_CLIENT_PROP_DBUS_OBJECT:
+ *
+ * String to access property #DbusmenuClient:dbus-object
+ */
#define DBUSMENU_CLIENT_PROP_DBUS_OBJECT "dbus-object"
+/**
+ * DBUSMENU_CLIENT_PROP_STATUS:
+ *
+ * String to access property #DbusmenuClient:status
+ */
+#define DBUSMENU_CLIENT_PROP_STATUS "status"
+/**
+ * DBUSMENU_CLIENT_PROP_TEXT_DIRECTION:
+ *
+ * String to access property #DbusmenuClient:text-direction
+ */
+#define DBUSMENU_CLIENT_PROP_TEXT_DIRECTION "text-direction"
+/**
+ * DBUSMENU_CLIENT_TYPES_DEFAULT:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * a standard menu item.
+ */
#define DBUSMENU_CLIENT_TYPES_DEFAULT "standard"
+/**
+ * DBUSMENU_CLIENT_TYPES_SEPARATOR:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * a separator menu item.
+ */
#define DBUSMENU_CLIENT_TYPES_SEPARATOR "separator"
+/**
+ * DBUSMENU_CLIENT_TYPES_IMAGE:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * an image menu item. Deprecated as standard menu items now
+ * support images as well.
+ */
#define DBUSMENU_CLIENT_TYPES_IMAGE "standard"
typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate;
@@ -62,6 +135,7 @@ typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate;
DbusmenuClientClass:
@parent_class: #GObjectClass
@layout_updated: Slot for #DbusmenuClient::layout-updated.
+ @root_changed: Slot for #DbusmenuClient::root-changed.
@new_menuitem: Slot for #DbusmenuClient::new-menuitem.
@item_activate: Slot for #DbusmenuClient::item-activate.
@event_result: Slot for #DbusmenuClient::event-error.
@@ -97,7 +171,6 @@ struct _DbusmenuClientClass {
/**
DbusmenuClient:
- @parent: #GObject.
The client for a #DbusmenuServer creating a shared
object set of #DbusmenuMenuitem objects.
@@ -119,6 +192,9 @@ struct _DbusmenuClient {
The type handler is called when a dbusmenu item is created
with a matching type as setup in #dbusmenu_client_add_type_handler
+
+ Return value: #TRUE if the type has been handled. #FALSE if this
+ function was somehow unable to handle it.
*/
typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
@@ -146,15 +222,8 @@ gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * cli
DbusmenuClientTypeHandler newfunc,
gpointer user_data,
DbusmenuClientTypeDestroyHandler destroy_func);
-void dbusmenu_client_send_event (DbusmenuClient * client,
- gint id,
- const gchar * name,
- GVariant * variant,
- guint timestamp);
-void dbusmenu_client_send_about_to_show(DbusmenuClient * client,
- gint id,
- void (*cb) (gpointer user_data),
- gpointer cb_data);
+DbusmenuTextDirection dbusmenu_client_get_text_direction (DbusmenuClient * client);
+DbusmenuStatus dbusmenu_client_get_status (DbusmenuClient * client);
/**
SECTION:client
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index c0831e5..829c16e 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -171,6 +171,24 @@ License version 3 and version 2.1 along with this program. If not, see
</dox:d>
</property>
+ <property name="text-direction" 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-
+ to-right the string is "ltr" for right-to-left it is "rtl".
+ </dox:d>
+ </property>
+
+ <property name="state" 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
+ were referring to them or they accessors were being highlighted.
+ This property can have two values: "normal" in almost all cases and
+ "notice" when they should have a higher priority to be shown.
+ </dox:d>
+ </property>
+
<!-- Functions -->
<method name="GetLayout">
diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c
index 3ad5d76..c05ef38 100644
--- a/libdbusmenu-glib/defaults.c
+++ b/libdbusmenu-glib/defaults.c
@@ -156,7 +156,7 @@ entry_destroy (gpointer entry)
static DbusmenuDefaults * default_defaults = NULL;
-/**
+/*
* dbusmenu_defaults_ref_default:
*
* Get a reference to the default instance. If it doesn't exist this
@@ -177,7 +177,7 @@ dbusmenu_defaults_ref_default (void)
return default_defaults;
}
-/**
+/*
* dbusmenu_defaults_default_set:
* @defaults: The #DbusmenuDefaults object to add to
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
@@ -216,7 +216,7 @@ dbusmenu_defaults_default_set (DbusmenuDefaults * defaults, const gchar * type,
return;
}
-/**
+/*
* dbusmenu_defaults_default_get:
* @defaults: The default database to use
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
@@ -253,7 +253,7 @@ dbusmenu_defaults_default_get (DbusmenuDefaults * defaults, const gchar * type,
return entry->value;
}
-/**
+/*
* dbusmenu_defaults_default_get_type:
* @defaults: The default database to use
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
diff --git a/libdbusmenu-glib/defaults.h b/libdbusmenu-glib/defaults.h
index ab377f7..a1a8158 100644
--- a/libdbusmenu-glib/defaults.h
+++ b/libdbusmenu-glib/defaults.h
@@ -45,7 +45,7 @@ typedef struct _DbusmenuDefaults DbusmenuDefaults;
typedef struct _DbusmenuDefaultsClass DbusmenuDefaultsClass;
typedef struct _DbusmenuDefaultsPrivate DbusmenuDefaultsPrivate;
-/**
+/*
* DbusmenuDefaultsClass:
*
* All of the signals and functions for #DbusmenuDefaults
@@ -54,7 +54,7 @@ struct _DbusmenuDefaultsClass {
GObjectClass parent_class;
};
-/**
+/*
* DbusmenuDefaults:
*
* A singleton to hold all of the defaults for the menuitems
diff --git a/libdbusmenu-glib/enum-types.c.in b/libdbusmenu-glib/enum-types.c.in
new file mode 100644
index 0000000..9395f5f
--- /dev/null
+++ b/libdbusmenu-glib/enum-types.c.in
@@ -0,0 +1,116 @@
+/*** BEGIN file-header ***/
+/*
+Enums from the dbusmenu headers
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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/>
+*/
+
+#include "enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+/**
+ @enum_name@_get_type:
+
+ Builds a GLib type for the #@EnumName@ enumeration.
+
+ Return value: A unique #GType for the #@EnumName@ enum.
+*/
+GType
+@enum_name@_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL}
+ };
+
+ etype = g_@type@_register_static (g_intern_static_string("@EnumName@"), values);
+ }
+
+ return etype;
+}
+
+/**
+ @enum_name@_get_nick:
+ @value: The value of @EnumName@ to get the nick of
+
+ Looks up in the enum table for the nick of @value.
+
+ Return value: The nick for the given value or #NULL on error
+*/
+const gchar *
+@enum_name@_get_nick (@EnumName@ value)
+{
+ GEnumClass * class = G_ENUM_CLASS(g_type_class_ref(@enum_name@_get_type()));
+ g_return_val_if_fail(class != NULL, NULL);
+
+ const gchar * ret = NULL;
+ GEnumValue * val = g_enum_get_value(class, value);
+ if (val != NULL) {
+ ret = val->value_nick;
+ }
+
+ g_type_class_unref(class);
+ return ret;
+}
+
+/**
+ @enum_name@_get_value_from_nick:
+ @nick: The enum nick to lookup
+
+ Looks up in the enum table for the value of @nick.
+
+ Return value: The value for the given @nick
+*/
+@EnumName@
+@enum_name@_get_value_from_nick (const gchar * nick)
+{
+ GEnumClass * class = G_ENUM_CLASS(g_type_class_ref(@enum_name@_get_type()));
+ g_return_val_if_fail(class != NULL, 0);
+
+ @EnumName@ ret = 0;
+ GEnumValue * val = g_enum_get_value_by_nick(class, nick);
+ if (val != NULL) {
+ ret = val->value;
+ }
+
+ g_type_class_unref(class);
+ return ret;
+}
+
+
+/*** END value-tail ***/
diff --git a/libdbusmenu-glib/enum-types.h.in b/libdbusmenu-glib/enum-types.h.in
new file mode 100644
index 0000000..488b615
--- /dev/null
+++ b/libdbusmenu-glib/enum-types.h.in
@@ -0,0 +1,62 @@
+/*** BEGIN file-header ***/
+/*
+Enums from the dbusmenu headers
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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_ENUM_TYPES_H__
+#define __DBUSMENU_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-tail ***/
+
+G_END_DECLS
+
+#endif /* __DBUSMENU_ENUM_TYPES_H__ */
+/*** END file-tail ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from file: "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+const gchar * @enum_name@_get_nick (@EnumName@ value) G_GNUC_CONST;
+@EnumName@ @enum_name@_get_value_from_nick (const gchar * nick) G_GNUC_CONST;
+/**
+ DBUSMENU_TYPE_@ENUMSHORT@:
+
+ Gets the #GType value for the type associated with the
+ #@EnumName@ enumerated type.
+*/
+#define DBUSMENU_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+
+/*** END value-header ***/
diff --git a/libdbusmenu-glib/menuitem-marshal.list b/libdbusmenu-glib/menuitem-marshal.list
index e3cb272..4382ed7 100644
--- a/libdbusmenu-glib/menuitem-marshal.list
+++ b/libdbusmenu-glib/menuitem-marshal.list
@@ -4,3 +4,4 @@ VOID: OBJECT, UINT
VOID: OBJECT
VOID: VOID
VOID: UINT
+BOOLEAN: STRING, VARIANT, UINT
diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h
index 89319dc..336769d 100644
--- a/libdbusmenu-glib/menuitem-private.h
+++ b/libdbusmenu-glib/menuitem-private.h
@@ -38,6 +38,7 @@ gboolean dbusmenu_menuitem_realized (DbusmenuMenuitem * mi);
void dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi);
GVariant * dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** properties);
gboolean dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * property);
+gboolean dbusmenu_menuitem_exposed (DbusmenuMenuitem * mi);
G_END_DECLS
diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h
index 2a22efe..ee988d8 100644
--- a/libdbusmenu-glib/menuitem-proxy.h
+++ b/libdbusmenu-glib/menuitem-proxy.h
@@ -67,8 +67,7 @@ struct _DbusmenuMenuitemProxyClass {
};
/**
- DbusmeneMenuitemProxy:
- @parent: The instance of #DbusmenuMenuitem
+ DbusmenuMenuitemProxy:
Public instance data for a #DbusmenuMenuitemProxy.
*/
@@ -83,6 +82,17 @@ GType dbusmenu_menuitem_proxy_get_type (void);
DbusmenuMenuitemProxy * dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi);
DbusmenuMenuitem * dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi);
+/**
+ * SECTION:menuitem-proxy
+ * @short_description: A menuitem that proxies from another menuitem
+ * @stability: Unstable
+ * @include: libdbusmenu-glib/menuitem-proxy.h
+ *
+ * This small object allows for proxying all the properties from a remote
+ * menuitem to a new object that can be moved around appropriately within
+ * the new menu structure.
+ */
+
G_END_DECLS
#endif
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index ee18fab..fb138b6 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -61,6 +61,8 @@ struct _DbusmenuMenuitemPrivate
gboolean root;
gboolean realized;
DbusmenuDefaults * defaults;
+ gboolean exposed;
+ DbusmenuMenuitem * parent;
};
/* Signals */
@@ -73,6 +75,7 @@ enum {
REALIZED,
SHOW_TO_USER,
ABOUT_TO_SHOW,
+ EVENT,
LAST_SIGNAL
};
@@ -246,6 +249,23 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass)
NULL, NULL,
_dbusmenu_menuitem_marshal_VOID__VOID,
G_TYPE_BOOLEAN, 0, G_TYPE_NONE);
+ /**
+ DbusmenuMenuitem::event:
+ @arg0: The #DbusmenuMenuitem object.
+ @arg1: Name of the event
+ @arg2: Information passed along with the event
+ @arg3: X11 timestamp of when the event happened
+
+ Emitted when an event is passed through. The event is signalled
+ after handle_event is called.
+ */
+ signals[EVENT] = g_signal_new(DBUSMENU_MENUITEM_SIGNAL_EVENT,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(DbusmenuMenuitemClass, event),
+ g_signal_accumulator_true_handled, NULL,
+ _dbusmenu_menuitem_marshal_BOOLEAN__STRING_VARIANT_UINT,
+ G_TYPE_BOOLEAN, 3, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_UINT);
g_object_class_install_property (object_class, PROP_ID,
g_param_spec_int(PROP_ID_S, "ID for the menu item",
@@ -316,6 +336,7 @@ dbusmenu_menuitem_init (DbusmenuMenuitem *self)
priv->realized = FALSE;
priv->defaults = dbusmenu_defaults_ref_default();
+ priv->exposed = FALSE;
return;
}
@@ -337,6 +358,11 @@ dbusmenu_menuitem_dispose (GObject *object)
priv->defaults = NULL;
}
+ if (priv->parent) {
+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+ priv->parent = NULL;
+ }
+
G_OBJECT_CLASS (dbusmenu_menuitem_parent_class)->dispose (object);
return;
}
@@ -563,11 +589,12 @@ dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi)
/* For all the taken children we need to signal
that they were removed */
static void
-take_children_signal (gpointer data, gpointer user_data)
+take_children_helper (gpointer data, gpointer user_data)
{
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
#endif
+ dbusmenu_menuitem_unparent(DBUSMENU_MENUITEM(data));
g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
return;
}
@@ -593,7 +620,7 @@ dbusmenu_menuitem_take_children (DbusmenuMenuitem * mi)
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
GList * children = priv->children;
priv->children = NULL;
- g_list_foreach(children, take_children_signal, mi);
+ g_list_foreach(children, take_children_helper, mi);
dbusmenu_menuitem_property_remove(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY);
@@ -702,6 +729,10 @@ dbusmenu_menuitem_child_append (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -734,6 +765,10 @@ dbusmenu_menuitem_child_prepend (DbusmenuMenuitem * mi, DbusmenuMenuitem * child
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -764,8 +799,14 @@ dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
+ if (dbusmenu_menuitem_get_parent(child) != mi) {
+ g_warning("Trying to remove a child that doesn't believe we're it's parent.");
+ return FALSE;
+ }
+
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
priv->children = g_list_remove(priv->children, child);
+ dbusmenu_menuitem_unparent(child);
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
#endif
@@ -800,6 +841,10 @@ dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem *
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -935,6 +980,84 @@ dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id)
}
/**
+ * dbusmenu_menuitem_set_parent:
+ * @mi: The #DbusmenuMenuitem for which to set the parent
+ * @parent: The new parent #DbusmenuMenuitem
+ *
+ * Sets the parent of @mi to @parent. If @mi already
+ * has a parent, then this call will fail. The parent will
+ * be set automatically when using the usual methods to add a
+ * child menuitem, so this function should not normally be
+ * called directly
+ *
+ * Return value: Whether the parent was set successfully
+ */
+gboolean
+dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ if (priv->parent != NULL) {
+ g_warning ("Menu item already has a parent");
+ return FALSE;
+ }
+
+ priv->parent = parent;
+ g_object_add_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+
+ return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_unparent:
+ * @mi: The #DbusmenuMenuitem to unparent
+ *
+ * Unparents the menu item @mi. If @mi doesn't have a
+ * parent, then this call will fail. The menuitem will
+ * be unparented automatically when using the usual methods
+ * to delete a child menuitem, so this function should not
+ * normally be called directly
+ *
+ * Return value: Whether the menu item was unparented successfully
+ */
+gboolean
+dbusmenu_menuitem_unparent (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ if (priv->parent == NULL) {
+ g_warning("Menu item doesn't have a parent");
+ return FALSE;
+ }
+
+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+ priv->parent = NULL;
+
+ return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_get_parent:
+ * @mi: The #DbusmenuMenuitem for which to inspect the parent
+ *
+ * This function looks up the parent of @mi
+ *
+ * Return value: (transfer none): The parent of this menu item
+ */
+DbusmenuMenuitem *
+dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ return priv->parent;
+}
+
+/**
* dbusmenu_menuitem_property_set:
* @mi: The #DbusmenuMenuitem to set the property on.
* @property: Name of the property to set.
@@ -1025,31 +1148,34 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
g_return_val_if_fail(property != NULL, FALSE);
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ GVariant * default_value = NULL;
- const gchar * type = menuitem_get_type(mi);
-
- /* 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) {
- /* If we have an expected type we should check to see if
- the value we've been given is of the same type and generate
- a warning if it isn't */
- if (!g_variant_is_of_type(value, default_type)) {
- 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));
+ if (value != NULL) {
+ const gchar * type = menuitem_get_type(mi);
+
+ /* 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) {
+ /* If we have an expected type we should check to see if
+ the value we've been given is of the same type and generate
+ a warning if it isn't */
+ if (!g_variant_is_of_type(value, default_type)) {
+ 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. */
- GVariant * 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) {
+ /* 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;
+ }
}
}
@@ -1210,7 +1336,7 @@ dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * propert
/**
- * dbusmenu_menuitem_property_exit:
+ * dbusmenu_menuitem_property_exist:
* @mi: The #DbusmenuMenuitem to look for the property on.
* @property: The property to look for.
*
@@ -1343,7 +1469,7 @@ dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** prop
GVariant * final_variant = NULL;
- if (g_hash_table_size(priv->properties) > 0) {
+ if ((properties == NULL || properties[0] == NULL) && g_hash_table_size(priv->properties) > 0) {
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
@@ -1352,6 +1478,33 @@ dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** prop
final_variant = g_variant_builder_end(&builder);
}
+ if (properties != NULL) {
+ GVariantBuilder builder;
+ gboolean builder_init = FALSE;
+ int i = 0; const gchar * prop;
+
+ for (prop = properties[i]; prop != NULL; prop = properties[++i]) {
+ GVariant * propvalue = dbusmenu_menuitem_property_get_variant(mi, prop);
+
+ if (propvalue == NULL) {
+ continue;
+ }
+
+ if (!builder_init) {
+ builder_init = TRUE;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ }
+
+ GVariant * dict = g_variant_new_dict_entry(g_variant_new_string((gchar *)prop),
+ g_variant_new_variant((GVariant *)propvalue));
+ g_variant_builder_add_value(&builder, dict);
+ }
+
+ if (builder_init) {
+ final_variant = g_variant_builder_end(&builder);
+ }
+ }
+
return final_variant;
}
@@ -1409,6 +1562,8 @@ GVariant *
dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** properties, gint recurse)
{
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ priv->exposed = TRUE;
gint id = 0;
if (!dbusmenu_menuitem_get_root(mi)) {
@@ -1433,7 +1588,7 @@ dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** propertie
/* Pillage the children */
GList * children = dbusmenu_menuitem_get_children(mi);
- if (children == NULL && recurse != 0) {
+ if (children == NULL || recurse == 0) {
g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0));
} else {
GVariantBuilder childrenbuilder;
@@ -1515,9 +1670,13 @@ dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, GVari
#endif
DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi);
- if (class->handle_event != NULL) {
+ 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);
}
+
return;
}
@@ -1591,3 +1750,13 @@ dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * prop
g_warn_if_reached();
return FALSE;
}
+
+/* Check to see if this menu item has been sent into the bus yet or
+ not. If no one cares we can give less info */
+gboolean
+dbusmenu_menuitem_exposed (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ return priv->exposed;
+}
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index afd6084..f4eb989 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -42,47 +42,237 @@ G_BEGIN_DECLS
#define DBUSMENU_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_MENUITEM, DbusmenuMenuitemClass))
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED:
+ *
+ * String to attach to signal #DbusmenuServer::property-changed
+ */
#define DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED "property-changed"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED:
+ *
+ * String to attach to signal #DbusmenuServer::item-activated
+ */
#define DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED "item-activated"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED:
+ *
+ * String to attach to signal #DbusmenuServer::child-added
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED "child-added"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED:
+ *
+ * String to attach to signal #DbusmenuServer::child-removed
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED "child-removed"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED:
+ *
+ * String to attach to signal #DbusmenuServer::child-moved
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED "child-moved"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_REALIZED:
+ *
+ * String to attach to signal #DbusmenuServer::realized
+ */
#define DBUSMENU_MENUITEM_SIGNAL_REALIZED "realized"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID:
+ *
+ * ID to attach to signal #DbusmenuServer::realized
+ */
#define DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID (g_signal_lookup(DBUSMENU_MENUITEM_SIGNAL_REALIZED, DBUSMENU_TYPE_MENUITEM))
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER:
+ *
+ * String to attach to signal #DbusmenuServer::show-to-user
+ */
#define DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER "show-to-user"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW:
+ *
+ * String to attach to signal #DbusmenuServer::about-to-show
+ */
#define DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW "about-to-show"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_EVENT:
+ *
+ * String to attach to signal #DbusmenuServer::event
+ */
+#define DBUSMENU_MENUITEM_SIGNAL_EVENT "event"
+/**
+ * DBUSMENU_MENUITEM_PROP_TYPE:
+ *
+ * #DbusmenuMenuitem property used to represent what type of menuitem
+ * this object represents. Type: #G_VARIANT_TYPE_STRING.
+ */
#define DBUSMENU_MENUITEM_PROP_TYPE "type"
+/**
+ * DBUSMENU_MENUITEM_PROP_VISIBLE:
+ *
+ * #DbusmenuMenuitem property used to represent whether the menuitem
+ * should be shown or not. Type: #G_VARIANT_TYPE_BOOLEAN.
+ */
#define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
+/**
+ * DBUSMENU_MENUITEM_PROP_ENABLED:
+ *
+ * #DbusmenuMenuitem property used to represent whether the menuitem
+ * is clickable or not. Type: #G_VARIANT_TYPE_BOOLEAN.
+ */
#define DBUSMENU_MENUITEM_PROP_ENABLED "enabled"
+/**
+ * DBUSMENU_MENUITEM_PROP_LABEL:
+ *
+ * #DbusmenuMenuitem property used for the text on the menu item.
+ * Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_LABEL "label"
+/**
+ * DBUSMENU_MENUITEM_PROP_ICON_NAME:
+ *
+ * #DbusmenuMenuitem property that is the name of the icon under the
+ * Freedesktop.org icon naming spec. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_ICON_NAME "icon-name"
+/**
+ * DBUSMENU_MENUITEM_PROP_ICON_DATA:
+ *
+ * #DbusmenuMenuitem property that is the raw data of a custom icon
+ * used in the application. Type: #G_VARIANT_TYPE_VARIANT
+ *
+ * It is recommended that this is not set directly but instead the
+ * libdbusmenu-gtk library is used with the function dbusmenu_menuitem_property_set_image()
+ */
#define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
+/**
+ * DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE:
+ *
+ * #DbusmenuMenuitem property that says what type of toggle entry should
+ * be shown in the menu. Should be either #DBUSMENU_MENUITEM_TOGGLE_CHECK
+ * or #DBUSMENU_MENUITEM_TOGGLE_RADIO. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type"
+/**
+ * DBUSMENU_MENUITEM_PROP_TOGGLE_STATE:
+ *
+ * #DbusmenuMenuitem property that says what state a toggle entry should
+ * be shown as the menu. Should be either #DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED
+ * #DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED or #DBUSMENU_MENUITEM_TOGGLE_STATUE_UNKNOWN.
+ * Type: #G_VARIANT_TYPE_INT32
+ */
#define DBUSMENU_MENUITEM_PROP_TOGGLE_STATE "toggle-state"
+/**
+ * DBUSMENU_MENUITEM_PROP_SHORTCUT:
+ *
+ * #DbusmenuMenuitem property that is the entries that represent a shortcut
+ * to activate the menuitem. It is an array of arrays of strings.
+ * Type: #G_VARIANT_TYPE_ARRAY
+ *
+ * It is recommended that this is not set directly but instead the
+ * libdbusmenu-gtk library is used with the function dbusmenu_menuitem_property_set_shortcut()
+ */
#define DBUSMENU_MENUITEM_PROP_SHORTCUT "shortcut"
+/**
+ * DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY:
+ *
+ * #DbusmenuMenuitem property that tells how the children of this menuitem
+ * should be displayed. Most likely this will be unset or of the value
+ * #DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY "children-display"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_CHECK:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE to be a standard
+ * check mark item.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_RADIO:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE to be a standard
+ * radio item.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is empty.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED 0
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is filled.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED 1
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is undecided.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN -1
+/**
+ * DBUSMENU_MENUITEM_ICON_NAME_BLANK:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is undecided.
+ */
#define DBUSMENU_MENUITEM_ICON_NAME_BLANK "blank-icon"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_CONTROL:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * control key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_CONTROL "Control"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_ALT:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * alternate key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_ALT "Alt"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_SHIFT:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * shift key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_SHIFT "Shift"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_SUPER:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * super key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_SUPER "Super"
+/**
+ * DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY to have the
+ * subitems displayed as a submenu.
+ */
#define DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU "submenu"
typedef struct _DbusmenuMenuitemPrivate DbusmenuMenuitemPrivate;
/**
* DbusmenuMenuitem:
+ * @parent: Parent object
+ * @priv: Private data
*
* This is the #GObject based object that represents a menu
* item. It gets created the same on both the client and
@@ -113,16 +303,18 @@ typedef void (*dbusmenu_menuitem_about_to_show_cb) (DbusmenuMenuitem * mi, gpoin
/**
* dbusmenu_menuitem_buildvariant_slot_t:
* @mi: (in): Menu item that should be built from
+ * @properties: (allow-none): A list of properties that should be the only ones in the resulting variant structure
*
* This is the function that is called to represent this menu item
* as a variant. Should call it's own children.
*
- * Return value: (transfer full) A variant representing this item and it's children
+ * Return value: (transfer full): A variant representing this item and it's children
*/
typedef GVariant * (*dbusmenu_menuitem_buildvariant_slot_t) (DbusmenuMenuitem * mi, gchar ** properties);
/**
* DbusmenuMenuitemClass:
+ * @parent_class: Functions and signals from our parent
* @property_changed: Slot for #DbusmenuMenuitem::property-changed.
* @item_activated: Slot for #DbusmenuMenuitem::item-activated.
* @child_added: Slot for #DbusmenuMenuitem::child-added.
@@ -130,17 +322,19 @@ typedef GVariant * (*dbusmenu_menuitem_buildvariant_slot_t) (DbusmenuMenuitem *
* @child_moved: Slot for #DbusmenuMenuitem::child-moved.
* @realized: Slot for #DbusmenuMenuitem::realized.
* @about_to_show: Slot for #DbusmenuMenuitem::about-to-show.
- * @buildxml: Virtual function that appends the strings required to represent this menu item in the menu XML file.
+ * @buildvariant: Virtual function that appends the strings required to represent this menu item in the menu variant.
* @handle_event: This function is to override how events are handled by subclasses. Look at #dbusmenu_menuitem_handle_event for lots of good information.
* @send_about_to_show: Virtual function that notifies server that the client is about to show a menu.
* @show_to_user: Slot for #DbusmenuMenuitem::show-to-user.
- *
+ * @event: Slot for #DbsumenuMenuitem::event.
* @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.
+ *
+ * Functions and signals that every menuitem should know something
+ * about.
*/
typedef struct _DbusmenuMenuitemClass DbusmenuMenuitemClass;
struct _DbusmenuMenuitemClass
@@ -163,13 +357,14 @@ struct _DbusmenuMenuitemClass
void (*show_to_user) (DbusmenuMenuitem * mi, guint timestamp, gpointer cb_data);
gboolean (*about_to_show) (void);
+ void (*event) (const gchar * name, GVariant * value, guint timestamp);
+
/*< Private >*/
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
void (*reserved5) (void);
- void (*reserved6) (void);
};
GType dbusmenu_menuitem_get_type (void);
@@ -191,6 +386,10 @@ gboolean dbusmenu_menuitem_child_reorder (DbusmenuMenuitem * mi, DbusmenuMenuite
DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id);
DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
+gboolean dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
+gboolean dbusmenu_menuitem_unparent (DbusmenuMenuitem *mi);
+DbusmenuMenuitem * dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi);
+
gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
gboolean dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value);
gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index aa39991..e3fd2cd 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -30,11 +30,13 @@ License version 3 and version 2.1 along with this program. If not, see
#include "config.h"
#endif
+#include <glib/gi18n.h>
#include <gio/gio.h>
#include "menuitem-private.h"
#include "server.h"
#include "server-marshal.h"
+#include "enum-types.h"
#include "dbus-menu-clean.xml.h"
@@ -55,6 +57,9 @@ struct _DbusmenuServerPrivate
GCancellable * bus_lookup;
guint dbus_registration;
+ DbusmenuTextDirection text_direction;
+ DbusmenuStatus status;
+
GArray * prop_array;
guint property_idle;
};
@@ -77,7 +82,9 @@ enum {
PROP_0,
PROP_DBUS_OBJECT,
PROP_ROOT_NODE,
- PROP_VERSION
+ PROP_VERSION,
+ PROP_TEXT_DIRECTION,
+ PROP_STATUS
};
/* Errors */
@@ -124,6 +131,7 @@ static void get_property (GObject * obj,
guint id,
GValue * value,
GParamSpec * pspec);
+static void default_text_direction (DbusmenuServer * server);
static void register_object (DbusmenuServer * server);
static void bus_got_cb (GObject * obj,
GAsyncResult * result,
@@ -289,6 +297,16 @@ dbusmenu_server_class_init (DbusmenuServerClass *class)
"The version of the DBusmenu API that we're implementing.",
DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_TEXT_DIRECTION,
+ g_param_spec_enum(DBUSMENU_SERVER_PROP_TEXT_DIRECTION, "The default direction of text",
+ "The object that represents this set of menus on DBus",
+ DBUSMENU_TYPE_TEXT_DIRECTION, DBUSMENU_TEXT_DIRECTION_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_STATUS,
+ g_param_spec_enum(DBUSMENU_SERVER_PROP_STATUS, "Status of viewing the menus",
+ "Exports over DBus whether the menus should be given special visuals",
+ DBUSMENU_TYPE_STATUS, DBUSMENU_STATUS_NORMAL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
if (dbusmenu_node_info == NULL) {
GError * error = NULL;
@@ -348,6 +366,9 @@ dbusmenu_server_init (DbusmenuServer *self)
priv->bus_lookup = NULL;
priv->dbus_registration = 0;
+ default_text_direction(self);
+ priv->status = DBUSMENU_STATUS_NORMAL;
+
return;
}
@@ -463,6 +484,64 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
}
layout_update_signal(DBUSMENU_SERVER(obj));
break;
+ case PROP_TEXT_DIRECTION: {
+ DbusmenuTextDirection indir = g_value_get_enum(value);
+ DbusmenuTextDirection olddir = priv->text_direction;
+
+ /* If being set to none we need to go back to default, otherwise
+ we'll set things the way that we've been told */
+ if (indir == DBUSMENU_TEXT_DIRECTION_NONE) {
+ default_text_direction(DBUSMENU_SERVER(obj));
+ } else {
+ priv->text_direction = indir;
+ }
+
+ /* 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(&params, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add_value(&params, 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)));
+ g_variant_builder_add_value(&params, g_variant_new_array(NULL, &dict, 1));
+ g_variant_builder_add_value(&params, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0));
+ GVariant * vparams = g_variant_builder_end(&params);
+
+ g_dbus_connection_emit_signal(priv->bus,
+ NULL,
+ priv->dbusobject,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ vparams,
+ NULL);
+ }
+
+ break;
+ }
+ case PROP_STATUS: {
+ DbusmenuStatus instatus = g_value_get_enum(value);
+
+ /* 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(&params, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add_value(&params, 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)));
+ g_variant_builder_add_value(&params, g_variant_new_array(NULL, &dict, 1));
+ g_variant_builder_add_value(&params, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0));
+ GVariant * vparams = g_variant_builder_end(&params);
+
+ g_dbus_connection_emit_signal(priv->bus,
+ NULL,
+ priv->dbusobject,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ vparams,
+ NULL);
+ }
+
+ priv->status = instatus;
+ break;
+ }
default:
g_return_if_reached();
break;
@@ -486,6 +565,12 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
case PROP_VERSION:
g_value_set_uint(value, DBUSMENU_VERSION_NUMBER);
break;
+ case PROP_TEXT_DIRECTION:
+ g_value_set_enum(value, priv->text_direction);
+ break;
+ case PROP_STATUS:
+ g_value_set_enum(value, priv->status);
+ break;
default:
g_return_if_reached();
break;
@@ -494,6 +579,49 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
return;
}
+/* Determines the default text direction */
+static void
+default_text_direction (DbusmenuServer * server)
+{
+ DbusmenuTextDirection dir = DBUSMENU_TEXT_DIRECTION_NONE;
+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
+
+ const gchar * env = g_getenv("DBUSMENU_TEXT_DIRECTION");
+ if (env != NULL) {
+ if (g_strcmp0(env, "ltr") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ } else if (g_strcmp0(env, "rtl") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_RTL;
+ } else {
+ g_warning("Value of 'DBUSMENU_TEXT_DIRECTION' is '%s' which is not one of 'rtl' or 'ltr'", env);
+ }
+ }
+
+ if (dir == DBUSMENU_TEXT_DIRECTION_NONE) {
+ /* TRANSLATORS: This is the direction of the text and can
+ either be the value 'ltr' for left-to-right text (English)
+ or 'rtl' for right-to-left (Arabic). */
+ const gchar * default_dir = C_("default text direction", "ltr");
+
+ if (g_strcmp0(default_dir, "ltr") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ } else if (g_strcmp0(default_dir, "rtl") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_RTL;
+ } else {
+ g_warning("Translation has an invalid value '%s' for default text direction. Defaulting to left-to-right.", default_dir);
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ }
+ }
+
+ /* Shouldn't happen, but incase future patches make a mistake
+ this'll catch them */
+ g_return_if_fail(dir != DBUSMENU_TEXT_DIRECTION_NONE);
+
+ priv->text_direction = dir;
+
+ return;
+}
+
/* Register the object on the dbus bus */
static void
register_object (DbusmenuServer * server)
@@ -611,9 +739,16 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar *
/* None of these should happen */
g_return_val_if_fail(g_strcmp0(interface, DBUSMENU_INTERFACE) == 0, NULL);
g_return_val_if_fail(g_strcmp0(path, priv->dbusobject) == 0, NULL);
- g_return_val_if_fail(g_strcmp0(property, "version") == 0, NULL);
- return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
+ if (g_strcmp0(property, "version") == 0) {
+ return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
+ } else if (g_strcmp0(property, "text-direction") == 0) {
+ return g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction));
+ } else {
+ g_warning("Unknown property '%s'", property);
+ }
+
+ return NULL;
}
/* Handle actually signalling in the idle loop. This way we collect all
@@ -656,7 +791,7 @@ layout_update_signal (DbusmenuServer * server)
typedef struct _prop_idle_item_t prop_idle_item_t;
struct _prop_idle_item_t {
- gint id;
+ DbusmenuMenuitem * mi;
GArray * array;
};
@@ -686,6 +821,7 @@ prop_array_teardown (GArray * prop_array)
}
}
+ g_object_unref(G_OBJECT(iitem->mi));
g_array_free(iitem->array, TRUE);
}
@@ -719,6 +855,12 @@ menuitem_property_idle (gpointer user_data)
for (i = 0; i < priv->prop_array->len; i++) {
prop_idle_item_t * iitem = &g_array_index(priv->prop_array, prop_idle_item_t, i);
+ /* if it's not exposed we're going to block it's properties
+ from getting into the dbus message */
+ if (dbusmenu_menuitem_exposed(iitem->mi) == FALSE) {
+ continue;
+ }
+
GVariantBuilder dictbuilder;
gboolean dictinit = FALSE;
@@ -756,7 +898,7 @@ menuitem_property_idle (gpointer user_data)
GVariantBuilder tuplebuilder;
g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
- g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(iitem->id));
+ g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(dbusmenu_menuitem_get_id(iitem->mi)));
g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&dictbuilder));
if (!item_init) {
@@ -773,7 +915,7 @@ menuitem_property_idle (gpointer user_data)
GVariantBuilder tuplebuilder;
g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
- g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(iitem->id));
+ g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(dbusmenu_menuitem_get_id(iitem->mi)));
g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&removedictbuilder));
if (!removeitem_init) {
@@ -786,9 +928,11 @@ menuitem_property_idle (gpointer user_data)
}
GVariant * megadata[2];
+ gboolean gotsomething = FALSE;
if (item_init) {
megadata[0] = g_variant_builder_end(&itembuilder);
+ gotsomething = TRUE;
} else {
GError * error = NULL;
megadata[0] = g_variant_parse(G_VARIANT_TYPE("a(ia{sv})"), "[ ]", NULL, NULL, &error);
@@ -801,6 +945,7 @@ menuitem_property_idle (gpointer user_data)
if (removeitem_init) {
megadata[1] = g_variant_builder_end(&removeitembuilder);
+ gotsomething = TRUE;
} else {
GError * error = NULL;
megadata[1] = g_variant_parse(G_VARIANT_TYPE("a(ia(s))"), "[ ]", NULL, NULL, &error);
@@ -811,7 +956,7 @@ menuitem_property_idle (gpointer user_data)
}
}
- if (priv->dbusobject != NULL && priv->bus != NULL) {
+ if (gotsomething && priv->dbusobject != NULL && priv->bus != NULL) {
g_dbus_connection_emit_signal(priv->bus,
NULL,
priv->dbusobject,
@@ -854,7 +999,7 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
prop_idle_item_t * item = NULL;
for (i = 0; i < priv->prop_array->len; i++) {
prop_idle_item_t * iitem = &g_array_index(priv->prop_array, prop_idle_item_t, i);
- if (iitem->id == item_id) {
+ if (iitem->mi == mi) {
item = iitem;
break;
}
@@ -864,7 +1009,8 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
/* If not, we'll need to build ourselves one */
if (item == NULL) {
prop_idle_item_t myitem;
- myitem.id = item_id;
+ myitem.mi = mi;
+ g_object_ref(G_OBJECT(mi));
myitem.array = g_array_new(FALSE, FALSE, sizeof(prop_idle_prop_t));
g_array_append_val(priv->prop_array, myitem);
@@ -892,7 +1038,9 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
/* If so, we need to swap the value */
if (prop != NULL) {
- g_variant_unref(prop->variant);
+ if (prop->variant != NULL) {
+ g_variant_unref(prop->variant);
+ }
prop->variant = variant;
} else {
/* else we need to add it */
@@ -1458,5 +1606,97 @@ dbusmenu_server_set_root (DbusmenuServer * self, DbusmenuMenuitem * root)
return;
}
+/**
+ dbusmenu_server_get_text_direction:
+ @server: The #DbusmenuServer object to get the text direction from
+
+ Returns the value of the text direction that is being exported
+ over DBus for this server. It should relate to the direction
+ of the labels and other text fields that are being exported by
+ this server.
+
+ Return value: Text direction exported for this server.
+*/
+DbusmenuTextDirection
+dbusmenu_server_get_text_direction (DbusmenuServer * server)
+{
+ g_return_val_if_fail(DBUSMENU_IS_SERVER(server), DBUSMENU_TEXT_DIRECTION_NONE);
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_TEXT_DIRECTION);
+ g_object_get_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_TEXT_DIRECTION, &val);
+
+ DbusmenuTextDirection retval = g_value_get_enum(&val);
+ g_value_unset(&val);
+ return retval;
+}
+
+/**
+ dbusmenu_server_set_text_direction:
+ @server: The #DbusmenuServer object to set the text direction on
+ @dir: Direction of the text
+
+ Sets the text direction that should be exported over DBus for
+ this server. If the value is set to #DBUSMENU_TEXT_DIRECTION_NONE
+ the default detection will be used for setting the value and
+ exported over DBus.
+*/
+void
+dbusmenu_server_set_text_direction (DbusmenuServer * server, DbusmenuTextDirection dir)
+{
+ g_return_if_fail(DBUSMENU_IS_SERVER(server));
+ g_return_if_fail(dir == DBUSMENU_TEXT_DIRECTION_NONE || dir == DBUSMENU_TEXT_DIRECTION_LTR || dir == DBUSMENU_TEXT_DIRECTION_RTL);
+
+ GValue newval = {0};
+ g_value_init(&newval, DBUSMENU_TYPE_TEXT_DIRECTION);
+ g_value_set_enum(&newval, dir);
+ g_object_set_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_TEXT_DIRECTION, &newval);
+ g_value_unset(&newval);
+ return;
+}
+/**
+ dbusmenu_server_get_status:
+ @server: The #DbusmenuServer to get the status from
+
+ Gets the current statust hat the server is sending out over
+ DBus.
+
+ Return value: The current status the server is sending
+*/
+DbusmenuStatus
+dbusmenu_server_get_status (DbusmenuServer * server)
+{
+ g_return_val_if_fail(DBUSMENU_IS_SERVER(server), DBUSMENU_STATUS_NORMAL);
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_STATUS);
+ g_object_get_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_STATUS, &val);
+
+ DbusmenuStatus retval = g_value_get_enum(&val);
+ g_value_unset(&val);
+
+ return retval;
+}
+
+/**
+ dbusmenu_server_set_status:
+ @server: The #DbusmenuServer to set the status on
+ @status: Status value to set on the server
+
+ Changes the status of the server.
+*/
+void
+dbusmenu_server_set_status (DbusmenuServer * server, DbusmenuStatus status)
+{
+ g_return_if_fail(DBUSMENU_IS_SERVER(server));
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_STATUS);
+ g_value_set_enum(&val, status);
+ g_object_set_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_STATUS, &val);
+ g_value_unset(&val);
+
+ return;
+}
diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h
index 5668258..80b7abb 100644
--- a/libdbusmenu-glib/server.h
+++ b/libdbusmenu-glib/server.h
@@ -33,6 +33,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include <glib-object.h>
#include "menuitem.h"
+#include "types.h"
G_BEGIN_DECLS
@@ -43,15 +44,67 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_SERVER))
#define DBUSMENU_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_SERVER, DbusmenuServerClass))
+/**
+ * DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::item-property-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "item-property-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_ID_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::item-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "item-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED:
+ *
+ * String to attach to signal #DbusmenuServer::layout-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED "layout-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_ITEM_ACTIVATION:
+ *
+ * String to attach to signal #DbusmenuServer::item-activation-requested
+ */
#define DBUSMENU_SERVER_SIGNAL_ITEM_ACTIVATION "item-activation-requested"
+/**
+ * DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::layout-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED
+/**
+ * DBUSMENU_SERVER_PROP_DBUS_OBJECT:
+ *
+ * String to access property #DbusmenuServer:dbus-object
+ */
#define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object"
+/**
+ * DBUSMENU_SERVER_PROP_ROOT_NODE:
+ *
+ * String to access property #DbusmenuServer:root-node
+ */
#define DBUSMENU_SERVER_PROP_ROOT_NODE "root-node"
+/**
+ * DBUSMENU_SERVER_PROP_VERSION:
+ *
+ * String to access property #DbusmenuServer:version
+ */
#define DBUSMENU_SERVER_PROP_VERSION "version"
+/**
+ * DBUSMENU_SERVER_PROP_TEXT_DIRECTION:
+ *
+ * String to access property #DbusmenuServer:text-direction
+ */
+#define DBUSMENU_SERVER_PROP_TEXT_DIRECTION "text-direction"
+/**
+ * DBUSMENU_SERVER_PROP_STATUS:
+ *
+ * String to access property #DbusmenuServer:status
+ */
+#define DBUSMENU_SERVER_PROP_STATUS "status"
typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
@@ -61,8 +114,7 @@ typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
@id_prop_update: Slot for #DbusmenuServer::id-prop-update.
@id_update: Slot for #DbusmenuServer::id-update.
@layout_updated: Slot for #DbusmenuServer::layout-update.
- @item_activation_requested: Slot for #DbusmenuServer::item-activation-requested.
-
+ @item_activation: Slot for #DbusmenuServer::item-activation-requested.
@reserved1: Reserved for future use.
@reserved2: Reserved for future use.
@reserved3: Reserved for future use.
@@ -93,7 +145,6 @@ struct _DbusmenuServerClass {
/**
DbusmenuServer:
- @parent: #GObject
A server which represents a sharing of a set of
#DbusmenuMenuitems across DBus to a #DbusmenuClient.
@@ -106,12 +157,19 @@ struct _DbusmenuServer {
DbusmenuServerPrivate * priv;
};
-GType dbusmenu_server_get_type (void);
-DbusmenuServer * dbusmenu_server_new (const gchar * object);
-void dbusmenu_server_set_root (DbusmenuServer * server, DbusmenuMenuitem * root);
+GType dbusmenu_server_get_type (void);
+DbusmenuServer * dbusmenu_server_new (const gchar * object);
+void dbusmenu_server_set_root (DbusmenuServer * self,
+ DbusmenuMenuitem * root);
+DbusmenuTextDirection dbusmenu_server_get_text_direction (DbusmenuServer * server);
+void dbusmenu_server_set_text_direction (DbusmenuServer * server,
+ DbusmenuTextDirection dir);
+DbusmenuStatus dbusmenu_server_get_status (DbusmenuServer * server);
+void dbusmenu_server_set_status (DbusmenuServer * server,
+ DbusmenuStatus status);
/**
- SECIONT:server
+ SECTION:server
@short_description: The server signals changed and
updates on a tree of #DbusmenuMenuitem objecs.
@stability: Unstable
diff --git a/libdbusmenu-glib/types.h b/libdbusmenu-glib/types.h
new file mode 100644
index 0000000..03ae801
--- /dev/null
+++ b/libdbusmenu-glib/types.h
@@ -0,0 +1,76 @@
+/*
+Types that are used in several objects.
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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_TYPES_H__
+#define __DBUSMENU_TYPES_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ DbusmenuTextDirection:
+ @DBUSMENU_TEXT_DIRECTION_NONE: Unspecified text direction
+ @DBUSMENU_TEXT_DIRECTION_LTR: Left-to-right text direction
+ @DBUSMENU_TEXT_DIRECTION_RTL: Right-to-left text direction
+
+ The direction of text that the strings that this server
+ will be sending strings as.
+*/
+typedef enum { /*< prefix=DBUSMENU_TEXT_DIRECTION >*/
+ DBUSMENU_TEXT_DIRECTION_NONE, /*< nick=none >*/
+ DBUSMENU_TEXT_DIRECTION_LTR, /*< nick=ltr >*/
+ DBUSMENU_TEXT_DIRECTION_RTL /*< nick=rtl >*/
+} DbusmenuTextDirection;
+
+/**
+ DbusmenuStatus:
+ @DBUSMENU_STATUS_NORMAL: Everything is normal
+ @DBUSMENU_STATUS_NOTICE: The menus should be shown at a higher priority
+
+ Tracks how the menus should be presented to the user.
+*/
+typedef enum { /*< prefix=DBUSMENU_STATUS >*/
+ DBUSMENU_STATUS_NORMAL, /*< nick=normal >*/
+ DBUSMENU_STATUS_NOTICE /*< nick=notice >*/
+} DbusmenuStatus;
+
+/**
+ SECTION:types
+ @short_description: Types that are used by both client and
+ server.
+ @stability: Unstable
+ @include: libdbusmenu-glib/types.h
+
+ Enums that are used to describe states of the server across the
+ bus. They are sent over dbus using their nicks but then turned
+ back into enums by the client.
+*/
+G_END_DECLS
+
+#endif /* __DBUSMENU_TYPES_H__ */
+
diff --git a/libdbusmenu-gtk/client.h b/libdbusmenu-gtk/client.h
index c986a5d..75b59a0 100644
--- a/libdbusmenu-gtk/client.h
+++ b/libdbusmenu-gtk/client.h
@@ -41,20 +41,28 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_GTKCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_GTKCLIENT_TYPE))
#define DBUSMENU_GTKCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_GTKCLIENT_TYPE, DbusmenuGtkClientClass))
+/**
+ * DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED:
+ *
+ * String to attach to signal #DbusmenuClient::root-changed
+ */
#define DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED
typedef struct _DbusmenuGtkClientPrivate DbusmenuGtkClientPrivate;
/**
- DbusmenuGtkClientClass:
- @parent_class: #GtkMenuClass
- @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.
-*/
+ * DbusmenuGtkClientClass:
+ * @parent_class: #GtkMenuClass
+ * @root_changed: Slot for signal #DbusmenuGtkClient::root-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.
+ *
+ * Functions and signal slots for using a #DbusmenuGtkClient
+ */
typedef struct _DbusmenuGtkClientClass DbusmenuGtkClientClass;
struct _DbusmenuGtkClientClass {
DbusmenuClientClass parent_class;
@@ -72,9 +80,11 @@ struct _DbusmenuGtkClientClass {
};
/**
- DbusmenuGtkClient:
- @parent: #GtkMenu
-*/
+ * DbusmenuGtkClient:
+ *
+ * A subclass of #DbusmenuClient to add functionality with regarding
+ * building GTK items out of the abstract tree.
+ */
typedef struct _DbusmenuGtkClient DbusmenuGtkClient;
struct _DbusmenuGtkClient {
DbusmenuClient parent;
@@ -94,10 +104,10 @@ GtkAccelGroup * dbusmenu_gtkclient_get_accel_group (DbusmenuGtkClient * client);
void dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * item, GtkMenuItem * gmi, DbusmenuMenuitem * parent);
/**
- SECTION:gtkmenu
- @short_description: A GTK Menu Object that syncronizes over DBus
+ SECTION:client
+ @short_description: A subclass of #DbusmenuClient adding GTK level features
@stability: Unstable
- @include: libdbusmenu-gtk/menu.h
+ @include: libdbusmenu-gtk/client.h
In general, this is just a #GtkMenu, why else would you care? Oh,
because this menu is created by someone else on a server that exists
@@ -115,8 +125,6 @@ void dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuit
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
diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c
index 2fd6fba..3652ceb 100644
--- a/libdbusmenu-gtk/genericmenuitem.c
+++ b/libdbusmenu-gtk/genericmenuitem.c
@@ -32,7 +32,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "genericmenuitem.h"
-/**
+/*
GenericmenuitemPrivate:
@check_type: What type of check we have, or none at all.
@state: What the state of our check is.
diff --git a/libdbusmenu-gtk/genericmenuitem.h b/libdbusmenu-gtk/genericmenuitem.h
index 3c4af0c..5e3c640 100644
--- a/libdbusmenu-gtk/genericmenuitem.h
+++ b/libdbusmenu-gtk/genericmenuitem.h
@@ -48,7 +48,7 @@ typedef struct _GenericmenuitemPrivate GenericmenuitemPrivate;
typedef enum _GenericmenuitemCheckType GenericmenuitemCheckType;
typedef enum _GenericmenuitemState GenericmenuitemState;
-/**
+/*
GenericmenuitemClass:
@parent_class: Our parent #GtkCheckMenuItemClass
*/
@@ -56,7 +56,7 @@ struct _GenericmenuitemClass {
GtkCheckMenuItemClass parent_class;
};
-/**
+/*
Genericmenuitem:
@parent: Our parent #GtkCheckMenuItem
*/
diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c
index c2720ac..0b31069 100644
--- a/libdbusmenu-gtk/menu.c
+++ b/libdbusmenu-gtk/menu.c
@@ -103,7 +103,7 @@ menu_focus_cb(DbusmenuGtkMenu * menu, gpointer userdata)
if (priv->client != NULL) {
/* TODO: We should stop the display of the menu
until the about to show call returns. */
- dbusmenu_client_send_about_to_show(DBUSMENU_CLIENT(priv->client), 0, NULL, NULL);
+ dbusmenu_menuitem_send_about_to_show(priv->root, NULL, NULL);
}
return;
}
diff --git a/libdbusmenu-gtk/menu.h b/libdbusmenu-gtk/menu.h
index 896e466..c413ab8 100644
--- a/libdbusmenu-gtk/menu.h
+++ b/libdbusmenu-gtk/menu.h
@@ -45,15 +45,18 @@ G_BEGIN_DECLS
typedef struct _DbusmenuGtkMenuPrivate DbusmenuGtkMenuPrivate;
/**
- DbusmenuGtkMenuClass:
- @parent_class: #GtkMenuClass
- @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.
-*/
+ * DbusmenuGtkMenuClass:
+ * @parent_class: #GtkMenuClass
+ * @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.
+ *
+ * All of the subclassable functions and signal slots for a
+ * #DbusmenuGtkMenu.
+ */
typedef struct _DbusmenuGtkMenuClass DbusmenuGtkMenuClass;
struct _DbusmenuGtkMenuClass {
GtkMenuClass parent_class;
@@ -68,9 +71,11 @@ struct _DbusmenuGtkMenuClass {
};
/**
- DbusmenuGtkMenu:
- @parent: #GtkMenu
-*/
+ * DbusmenuGtkMenu:
+ *
+ * A #GtkMenu that is built using an abstract tree built from
+ * a #DbusmenuGtkClient.
+ */
typedef struct _DbusmenuGtkMenu DbusmenuGtkMenu;
struct _DbusmenuGtkMenu {
GtkMenu parent;
@@ -84,7 +89,7 @@ DbusmenuGtkMenu * dbusmenu_gtkmenu_new (gchar * dbus_name, gchar * dbus_object);
DbusmenuGtkClient * dbusmenu_gtkmenu_get_client (DbusmenuGtkMenu * menu);
/**
- SECTION:gtkmenu
+ SECTION:menu
@short_description: A GTK Menu Object that syncronizes over DBus
@stability: Unstable
@include: libdbusmenu-gtk/menu.h
@@ -105,8 +110,6 @@ DbusmenuGtkClient * dbusmenu_gtkmenu_get_client (DbusmenuGtkMenu * menu);
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
diff --git a/libdbusmenu-gtk/menuitem.h b/libdbusmenu-gtk/menuitem.h
index 6f009df..41f2187 100644
--- a/libdbusmenu-gtk/menuitem.h
+++ b/libdbusmenu-gtk/menuitem.h
@@ -45,6 +45,17 @@ gboolean dbusmenu_menuitem_property_set_shortcut_string (DbusmenuMenuitem * menu
gboolean dbusmenu_menuitem_property_set_shortcut_menuitem (DbusmenuMenuitem * menuitem, const GtkMenuItem * gmi);
void dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * key, GdkModifierType * modifier);
+/**
+ SECTION:menuitem
+ @short_description: Helpers for #DbusmenuMenuitem properties that require a GTK dependency
+ @stability: Unstable
+ @include: libdbusmenu-gtk/menuitem.h
+
+ Some property helpers can't be done without picking up a GTK+
+ dependency. So those sit in libdbusmenu-gtk but have very similar
+ prototypes to the code in libdbusmenu-glib so your code will
+ look consistent, just with the extra depedency.
+*/
G_END_DECLS
#endif
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index b910ee7..97f7979 100644
--- a/libdbusmenu-gtk/parser.c
+++ b/libdbusmenu-gtk/parser.c
@@ -109,56 +109,62 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
return recurse.parent;
}
-/* Called when the dbusmenu item that we're keeping around
- is finalized */
static void
-dbusmenu_cache_freed (gpointer data, GObject * obj)
+parse_data_free (gpointer data)
{
- /* If the dbusmenu item is killed we don't need to remove
- the weak ref as well. */
- g_object_steal_data(G_OBJECT(data), CACHED_MENUITEM);
-
- ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(obj), PARSER_DATA);
+ ParserData *pdata = (ParserData *)data;
if (pdata != NULL && pdata->label != NULL) {
- g_signal_handlers_disconnect_by_func(pdata->label, G_CALLBACK(label_notify_cb), obj);
+ g_signal_handlers_disconnect_matched(pdata->label, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(label_notify_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->label), (gpointer*)&pdata->label);
}
if (pdata != NULL && pdata->action != NULL) {
- g_signal_handlers_disconnect_by_func(pdata->action, G_CALLBACK(action_notify_cb), obj);
+ g_signal_handlers_disconnect_matched(pdata->action, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(action_notify_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->action), (gpointer*)&pdata->action);
}
if (pdata != NULL && pdata->widget != NULL) {
- g_signal_handlers_disconnect_by_func(pdata->widget, G_CALLBACK(widget_notify_cb), obj);
+ g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(widget_notify_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->widget), (gpointer*)&pdata->widget);
}
if (pdata != NULL && pdata->shell != NULL) {
- g_signal_handlers_disconnect_by_func(pdata->shell, G_CALLBACK(child_added_cb), obj);
+ g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(child_added_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell);
}
if (pdata != NULL && pdata->image != NULL) {
- g_signal_handlers_disconnect_by_func(pdata->image, G_CALLBACK(image_notify_cb), obj);
+ g_signal_handlers_disconnect_matched(pdata->image, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(image_notify_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image);
}
+ g_free(pdata);
+
return;
}
-/* Called if we replace the cache on the object with a new
- dbusmenu menuitem */
+/* Called when the dbusmenu item that we're keeping around
+ is finalized */
static void
-object_cache_freed (gpointer data)
+dbusmenu_item_freed (gpointer data, GObject * obj)
{
- // TODO: make this have access to both data and obj so we can call these
- //if (!G_IS_OBJECT(obj)) return;
- //g_object_weak_unref(G_OBJECT(obj), dbusmenu_cache_freed, data);
- //dbusmenu_cache_freed(data, obj);
+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(obj), PARSER_DATA);
- g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), data);
+ if (pdata != NULL && pdata->widget != NULL) {
+ g_object_steal_data(G_OBJECT(pdata->widget), CACHED_MENUITEM);
+ }
+}
+
+static void
+widget_freed (gpointer data, GObject * obj)
+{
+ g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), obj);
return;
}
@@ -198,10 +204,13 @@ new_menuitem (GtkWidget * widget)
DbusmenuMenuitem * item = dbusmenu_menuitem_new();
ParserData *pdata = g_new0 (ParserData, 1);
- g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, g_free);
+ g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, parse_data_free);
+
+ g_object_weak_ref(G_OBJECT(item), dbusmenu_item_freed, NULL);
+ g_object_weak_ref(G_OBJECT(widget), widget_freed, NULL);
- g_object_set_data_full(G_OBJECT(widget), CACHED_MENUITEM, item, object_cache_freed);
- g_object_weak_ref(G_OBJECT(item), dbusmenu_cache_freed, widget);
+ pdata->widget = widget;
+ g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget);
return item;
}
@@ -237,16 +246,16 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
if (recurse->parent == NULL) {
recurse->parent = new_menuitem(widget);
- }
- ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(recurse->parent), PARSER_DATA);
+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(recurse->parent), PARSER_DATA);
- pdata->shell = widget;
- g_signal_connect (G_OBJECT (widget),
- "child-added",
- G_CALLBACK (child_added_cb),
- recurse->parent);
- g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell);
+ pdata->shell = widget;
+ g_signal_connect (G_OBJECT (widget),
+ "child-added",
+ G_CALLBACK (child_added_cb),
+ recurse->parent);
+ g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell);
+ }
gtk_container_foreach (GTK_CONTAINER (widget),
(GtkCallback)parse_menu_structure_helper,
@@ -294,10 +303,6 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
/* Oops, let's tell our parents about us */
if (peek == NULL) {
- /* TODO: Should we set a weak ref on the parent? */
- g_object_set_data (G_OBJECT (thisitem),
- "dbusmenu-parent",
- recurse->parent);
gint pos = get_child_position (widget);
if (pos >= 0)
dbusmenu_menuitem_child_add_position (recurse->parent,
@@ -472,12 +477,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget)
DBUSMENU_MENUITEM_PROP_ENABLED,
sensitive);
- pdata->widget = widget;
g_signal_connect (widget,
"notify",
G_CALLBACK (widget_notify_cb),
mi);
- g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget);
return mi;
}
@@ -792,7 +795,7 @@ widget_notify_cb (GtkWidget *widget,
G_CALLBACK (widget_notify_cb),
child);
- DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (child), "dbusmenu-parent");
+ DbusmenuMenuitem *parent = dbusmenu_menuitem_get_parent (child);
if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (child))
{
diff --git a/libdbusmenu-gtk/parser.h b/libdbusmenu-gtk/parser.h
index a40d709..8187a8e 100644
--- a/libdbusmenu-gtk/parser.h
+++ b/libdbusmenu-gtk/parser.h
@@ -32,6 +32,20 @@ License version 3 and version 2.1 along with this program. If not, see
#include <libdbusmenu-glib/menuitem.h>
#include <gtk/gtk.h>
+G_BEGIN_DECLS
+
DbusmenuMenuitem * dbusmenu_gtk_parse_menu_structure (GtkWidget * widget);
+/**
+ SECTION:parser
+ @short_description: A parser of in-memory GTK menu trees
+ @stability: Unstable
+ @include: libdbusmenu-gtk/parser.h
+
+ The parser will take a GTK menu tree and attach it to a Dbusmenu menu
+ tree. Along with setting up all the signals for updates and destruction.
+ The returned item would be the root item of the given tree.
+*/
+G_END_DECLS
+
#endif /* DBUSMENU_GTK_PARSER_H__ */
diff --git a/libdbusmenu-gtk/serializablemenuitem.h b/libdbusmenu-gtk/serializablemenuitem.h
index db28a24..9bea89f 100644
--- a/libdbusmenu-gtk/serializablemenuitem.h
+++ b/libdbusmenu-gtk/serializablemenuitem.h
@@ -44,6 +44,11 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM))
#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemClass))
+/**
+ * DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM:
+ *
+ * String to access property #DbusmenuGtkSerializableMenuItem:dbusmenu-menuitem
+ */
#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM "dbusmenu-menuitem"
typedef struct _DbusmenuGtkSerializableMenuItem DbusmenuGtkSerializableMenuItem;
@@ -62,6 +67,8 @@ typedef struct _DbusmenuGtkSerializableMenuItemPrivate DbusmenuGtkSerializableMe
@_dbusmenu_gtk_serializable_menu_item_reserved4: Reserved for future use.
@_dbusmenu_gtk_serializable_menu_item_reserved5: Reserved for future use.
@_dbusmenu_gtk_serializable_menu_item_reserved6: Reserved for future use.
+
+ Signals and functions for #DbusmenuGtkSerializableMenuItem.
*/
struct _DbusmenuGtkSerializableMenuItemClass {
GtkMenuItemClass parent_class;
@@ -110,6 +117,17 @@ DbusmenuMenuitem * dbusmenu_gtk_serializable_menu_item_build_menuitem (Dbusmenu
void dbusmenu_gtk_serializable_menu_item_register_to_client (DbusmenuClient * client, GType item_type);
void dbusmenu_gtk_serializable_menu_item_set_menuitem (DbusmenuGtkSerializableMenuItem * smi, DbusmenuMenuitem * mi);
+/**
+ SECTION:serializablemenuitem
+ @short_description: A way to build #GtkMenuItems that can be sent over Dbusmenu
+ @stability: Unstable
+ @include: libdbusmenu-gtk/serializablemenuitem.h
+
+ Menuitems can subclass from this instead of #GtkMenuItem and
+ by providing the appropriate functions Dbusmenu will be able
+ to parse them and send them over the bus.
+*/
+
G_END_DECLS
#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a386915..d6ac240 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1 +1,2 @@
libdbusmenu-glib/defaults.c
+libdbusmenu-glib/server.c