summaryrefslogtreecommitdiff
path: root/applets/notification_area
diff options
context:
space:
mode:
Diffstat (limited to 'applets/notification_area')
-rw-r--r--applets/notification_area/Makefile.am112
-rw-r--r--applets/notification_area/Makefile.in964
-rw-r--r--applets/notification_area/fixedtip.c269
-rw-r--r--applets/notification_area/fixedtip.h72
-rw-r--r--applets/notification_area/main.c267
-rw-r--r--applets/notification_area/na-marshal.c167
-rw-r--r--applets/notification_area/na-marshal.h36
-rw-r--r--applets/notification_area/na-marshal.list3
-rw-r--r--applets/notification_area/na-tray-child.c539
-rw-r--r--applets/notification_area/na-tray-child.h75
-rw-r--r--applets/notification_area/na-tray-manager.c859
-rw-r--r--applets/notification_area/na-tray-manager.h101
-rw-r--r--applets/notification_area/na-tray.c837
-rw-r--r--applets/notification_area/na-tray.h71
-rw-r--r--applets/notification_area/notification-area-menu.xml3
-rw-r--r--applets/notification_area/org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in17
-rw-r--r--applets/notification_area/org.mate.panel.applet.NotificationAreaAppletFactory.service.in3
-rw-r--r--applets/notification_area/testtray.c220
18 files changed, 4615 insertions, 0 deletions
diff --git a/applets/notification_area/Makefile.am b/applets/notification_area/Makefile.am
new file mode 100644
index 00000000..8609eff9
--- /dev/null
+++ b/applets/notification_area/Makefile.am
@@ -0,0 +1,112 @@
+noinst_LTLIBRARIES = libtray.la
+noinst_PROGRAMS = testtray
+
+AM_CPPFLAGS = \
+ $(NOTIFICATION_AREA_CFLAGS) \
+ $(LIBMATE_PANEL_APPLET_CFLAGS) \
+ -I$(srcdir) \
+ -I$(srcdir)/../../libmate-panel-applet \
+ -I$(top_builddir)/libmate-panel-applet \
+ -DMATELOCALEDIR=\""$(datadir)/locale"\" \
+ -DG_LOG_DOMAIN=\""notification-area-applet"\" \
+ -DNOTIFICATION_AREA_MENU_UI_DIR=\""$(uidir)"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+AM_CFLAGS = $(WARN_CFLAGS)
+
+libtray_la_SOURCES = \
+ fixedtip.h \
+ fixedtip.c \
+ na-marshal.c \
+ na-marshal.h \
+ na-tray.c \
+ na-tray.h \
+ na-tray-child.c \
+ na-tray-child.h \
+ na-tray-manager.c \
+ na-tray-manager.h
+
+NOTIFICATION_AREA_SOURCES = main.c
+
+NOTIFICATION_AREA_LDADD = \
+ ../../libmate-panel-applet/libmate-panel-applet-3.la \
+ libtray.la \
+ $(X_LIBS) \
+ $(NOTIFICATION_AREA_LIBS) \
+ $(LIBMATE_PANEL_APPLET_LIBS)
+
+
+testtray_SOURCES = testtray.c
+testtray_LDADD = \
+ libtray.la \
+ $(X_LIBS) \
+ $(NOTIFICATION_AREA_LIBS)
+
+if NOTIFICATION_AREA_INPROCESS
+APPLET_IN_PROCESS = true
+APPLET_LOCATION = $(pkglibdir)/libnotification-area-applet.so
+
+notification_area_appletlibdir = $(pkglibdir)
+notification_area_appletlib_LTLIBRARIES = libnotification-area-applet.la
+libnotification_area_applet_la_SOURCES = $(NOTIFICATION_AREA_SOURCES)
+libnotification_area_applet_la_LIBADD = $(NOTIFICATION_AREA_LDADD)
+libnotification_area_applet_la_LDFLAGS = -module -avoid-version
+libnotification_area_applet_la_CFLAGS = $(AM_CFLAGS)
+else
+APPLET_IN_PROCESS = false
+APPLET_LOCATION = $(libexecdir)/notification-area-applet
+
+libexec_PROGRAMS = notification-area-applet
+notification_area_applet_SOURCES = $(NOTIFICATION_AREA_SOURCES)
+notification_area_applet_LDADD = $(NOTIFICATION_AREA_LDADD)
+notification_area_applet_CFLAGS = $(AM_CFLAGS)
+endif
+
+na-marshal.h: na-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN)$(GLIB_GENMARSHAL) $< --header --prefix=_na_marshal > $@
+
+na-marshal.c: na-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN)echo "#include \"na-marshal.h\"" > $@ && \
+ $(GLIB_GENMARSHAL) $< --body --prefix=_na_marshal >> $@
+
+BUILT_SOURCES = na-marshal.c na-marshal.h
+
+appletdir = $(datadir)/mate-panel/applets
+applet_in_files = org.mate.panel.NotificationAreaApplet.mate-panel-applet.in
+applet_DATA = $(applet_in_files:.mate-panel-applet.in=.mate-panel-applet)
+
+$(applet_in_files): $(applet_in_files).in Makefile
+ $(AM_V_GEN)sed \
+ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+ -e "s|\@IN_PROCESS\@|$(APPLET_IN_PROCESS)|" \
+ -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \
+ $< > $@
+
+@PANEL_INTLTOOL_MATE_PANEL_APPLET_RULE@
+
+if !NOTIFICATION_AREA_INPROCESS
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.mate.panel.applet.NotificationAreaAppletFactory.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+org.mate.panel.applet.NotificationAreaAppletFactory.service: $(service_in_files)
+ $(AM_V_GEN)sed \
+ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+ $< > $@
+endif
+
+uidir = $(datadir)/mate-panel/ui
+ui_DATA = notification-area-menu.xml
+
+EXTRA_DIST = \
+ org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in \
+ $(ui_DATA) \
+ $(service_in_files) \
+ na-marshal.list
+
+CLEANFILES = \
+ $(applet_DATA) \
+ $(applet_DATA).in \
+ $(service_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/applets/notification_area/Makefile.in b/applets/notification_area/Makefile.in
new file mode 100644
index 00000000..2f73b378
--- /dev/null
+++ b/applets/notification_area/Makefile.in
@@ -0,0 +1,964 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = testtray$(EXEEXT)
+@NOTIFICATION_AREA_INPROCESS_FALSE@libexec_PROGRAMS = notification-area-applet$(EXEEXT)
+subdir = applets/notification_area
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/d-type.m4 \
+ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mate-doc-utils.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(notification_area_appletlibdir)" \
+ "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(appletdir)" \
+ "$(DESTDIR)$(servicedir)" "$(DESTDIR)$(uidir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) \
+ $(notification_area_appletlib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = \
+ ../../libmate-panel-applet/libmate-panel-applet-3.la \
+ libtray.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+@NOTIFICATION_AREA_INPROCESS_TRUE@libnotification_area_applet_la_DEPENDENCIES = \
+@NOTIFICATION_AREA_INPROCESS_TRUE@ $(am__DEPENDENCIES_2)
+am__libnotification_area_applet_la_SOURCES_DIST = main.c
+am__objects_1 = libnotification_area_applet_la-main.lo
+@NOTIFICATION_AREA_INPROCESS_TRUE@am_libnotification_area_applet_la_OBJECTS = \
+@NOTIFICATION_AREA_INPROCESS_TRUE@ $(am__objects_1)
+libnotification_area_applet_la_OBJECTS = \
+ $(am_libnotification_area_applet_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnotification_area_applet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libnotification_area_applet_la_CFLAGS) $(CFLAGS) \
+ $(libnotification_area_applet_la_LDFLAGS) $(LDFLAGS) -o $@
+@NOTIFICATION_AREA_INPROCESS_TRUE@am_libnotification_area_applet_la_rpath = \
+@NOTIFICATION_AREA_INPROCESS_TRUE@ -rpath \
+@NOTIFICATION_AREA_INPROCESS_TRUE@ $(notification_area_appletlibdir)
+libtray_la_LIBADD =
+am_libtray_la_OBJECTS = fixedtip.lo na-marshal.lo na-tray.lo \
+ na-tray-child.lo na-tray-manager.lo
+libtray_la_OBJECTS = $(am_libtray_la_OBJECTS)
+PROGRAMS = $(libexec_PROGRAMS) $(noinst_PROGRAMS)
+am__notification_area_applet_SOURCES_DIST = main.c
+am__objects_2 = notification_area_applet-main.$(OBJEXT)
+@NOTIFICATION_AREA_INPROCESS_FALSE@am_notification_area_applet_OBJECTS = \
+@NOTIFICATION_AREA_INPROCESS_FALSE@ $(am__objects_2)
+notification_area_applet_OBJECTS = \
+ $(am_notification_area_applet_OBJECTS)
+@NOTIFICATION_AREA_INPROCESS_FALSE@notification_area_applet_DEPENDENCIES = \
+@NOTIFICATION_AREA_INPROCESS_FALSE@ $(am__DEPENDENCIES_2)
+notification_area_applet_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(notification_area_applet_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_testtray_OBJECTS = testtray.$(OBJEXT)
+testtray_OBJECTS = $(am_testtray_OBJECTS)
+testtray_DEPENDENCIES = libtray.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libnotification_area_applet_la_SOURCES) \
+ $(libtray_la_SOURCES) $(notification_area_applet_SOURCES) \
+ $(testtray_SOURCES)
+DIST_SOURCES = $(am__libnotification_area_applet_la_SOURCES_DIST) \
+ $(libtray_la_SOURCES) \
+ $(am__notification_area_applet_SOURCES_DIST) \
+ $(testtray_SOURCES)
+DATA = $(applet_DATA) $(service_DATA) $(ui_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLOCK_CFLAGS = @CLOCK_CFLAGS@
+CLOCK_EDS_ICONDIR = @CLOCK_EDS_ICONDIR@
+CLOCK_LIBS = @CLOCK_LIBS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+DLLTOOL = @DLLTOOL@
+DOC_USER_FORMATS = @DOC_USER_FORMATS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGG_SMCLIENT_CFLAGS = @EGG_SMCLIENT_CFLAGS@
+EGG_SMCLIENT_LIBS = @EGG_SMCLIENT_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FISH_CFLAGS = @FISH_CFLAGS@
+FISH_LIBS = @FISH_LIBS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_QUERYMODULES = @GIO_QUERYMODULES@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+HELP_DIR = @HELP_DIR@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMATE_PANEL_APPLET_CFLAGS = @LIBMATE_PANEL_APPLET_CFLAGS@
+LIBMATE_PANEL_APPLET_LIBS = @LIBMATE_PANEL_APPLET_LIBS@
+LIBMATE_PANEL_APPLET_MATECOMPONENT_CFLAGS = @LIBMATE_PANEL_APPLET_MATECOMPONENT_CFLAGS@
+LIBMATE_PANEL_APPLET_MATECOMPONENT_LIBS = @LIBMATE_PANEL_APPLET_MATECOMPONENT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MATE_PANEL_APPLET_LT_VERSION = @LIB_MATE_PANEL_APPLET_LT_VERSION@
+LIB_MATE_PANEL_APPLET_MATECOMPONENT_LT_VERSION = @LIB_MATE_PANEL_APPLET_MATECOMPONENT_LT_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MATECOMPONENT_ACT_IDLDIR = @MATECOMPONENT_ACT_IDLDIR@
+MATECOMPONENT_CFLAGS = @MATECOMPONENT_CFLAGS@
+MATECOMPONENT_IDLDIR = @MATECOMPONENT_IDLDIR@
+MATECOMPONENT_LIBS = @MATECOMPONENT_LIBS@
+MATECONFTOOL = @MATECONFTOOL@
+MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@
+MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@
+MATECORBA_IDL = @MATECORBA_IDL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NETWORK_MANAGER_CFLAGS = @NETWORK_MANAGER_CFLAGS@
+NETWORK_MANAGER_LIBS = @NETWORK_MANAGER_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOTIFICATION_AREA_CFLAGS = @NOTIFICATION_AREA_CFLAGS@
+NOTIFICATION_AREA_LIBS = @NOTIFICATION_AREA_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMF_DIR = @OMF_DIR@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PANEL_CFLAGS = @PANEL_CFLAGS@
+PANEL_INTLTOOL_MATE_PANEL_APPLET_RULE = @PANEL_INTLTOOL_MATE_PANEL_APPLET_RULE@
+PANEL_LIBS = @PANEL_LIBS@
+PANEL_MODULE_MATECOMPONENT_CFLAGS = @PANEL_MODULE_MATECOMPONENT_CFLAGS@
+PANEL_MODULE_MATECOMPONENT_LIBS = @PANEL_MODULE_MATECOMPONENT_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REBUILD = @REBUILD@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TZ_CFLAGS = @TZ_CFLAGS@
+TZ_LIBS = @TZ_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WNCKLET_CFLAGS = @WNCKLET_CFLAGS@
+WNCKLET_LIBS = @WNCKLET_LIBS@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XRANDR_CFLAGS = @XRANDR_CFLAGS@
+XRANDR_LIBS = @XRANDR_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+appletsdir = @appletsdir@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+modulesdir = @modulesdir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libtray.la
+AM_CPPFLAGS = \
+ $(NOTIFICATION_AREA_CFLAGS) \
+ $(LIBMATE_PANEL_APPLET_CFLAGS) \
+ -I$(srcdir) \
+ -I$(srcdir)/../../libmate-panel-applet \
+ -I$(top_builddir)/libmate-panel-applet \
+ -DMATELOCALEDIR=\""$(datadir)/locale"\" \
+ -DG_LOG_DOMAIN=\""notification-area-applet"\" \
+ -DNOTIFICATION_AREA_MENU_UI_DIR=\""$(uidir)"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+AM_CFLAGS = $(WARN_CFLAGS)
+libtray_la_SOURCES = \
+ fixedtip.h \
+ fixedtip.c \
+ na-marshal.c \
+ na-marshal.h \
+ na-tray.c \
+ na-tray.h \
+ na-tray-child.c \
+ na-tray-child.h \
+ na-tray-manager.c \
+ na-tray-manager.h
+
+NOTIFICATION_AREA_SOURCES = main.c
+NOTIFICATION_AREA_LDADD = \
+ ../../libmate-panel-applet/libmate-panel-applet-3.la \
+ libtray.la \
+ $(X_LIBS) \
+ $(NOTIFICATION_AREA_LIBS) \
+ $(LIBMATE_PANEL_APPLET_LIBS)
+
+testtray_SOURCES = testtray.c
+testtray_LDADD = \
+ libtray.la \
+ $(X_LIBS) \
+ $(NOTIFICATION_AREA_LIBS)
+
+@NOTIFICATION_AREA_INPROCESS_FALSE@APPLET_IN_PROCESS = false
+@NOTIFICATION_AREA_INPROCESS_TRUE@APPLET_IN_PROCESS = true
+@NOTIFICATION_AREA_INPROCESS_FALSE@APPLET_LOCATION = $(libexecdir)/notification-area-applet
+@NOTIFICATION_AREA_INPROCESS_TRUE@APPLET_LOCATION = $(pkglibdir)/libnotification-area-applet.so
+@NOTIFICATION_AREA_INPROCESS_TRUE@notification_area_appletlibdir = $(pkglibdir)
+@NOTIFICATION_AREA_INPROCESS_TRUE@notification_area_appletlib_LTLIBRARIES = libnotification-area-applet.la
+@NOTIFICATION_AREA_INPROCESS_TRUE@libnotification_area_applet_la_SOURCES = $(NOTIFICATION_AREA_SOURCES)
+@NOTIFICATION_AREA_INPROCESS_TRUE@libnotification_area_applet_la_LIBADD = $(NOTIFICATION_AREA_LDADD)
+@NOTIFICATION_AREA_INPROCESS_TRUE@libnotification_area_applet_la_LDFLAGS = -module -avoid-version
+@NOTIFICATION_AREA_INPROCESS_TRUE@libnotification_area_applet_la_CFLAGS = $(AM_CFLAGS)
+@NOTIFICATION_AREA_INPROCESS_FALSE@notification_area_applet_SOURCES = $(NOTIFICATION_AREA_SOURCES)
+@NOTIFICATION_AREA_INPROCESS_FALSE@notification_area_applet_LDADD = $(NOTIFICATION_AREA_LDADD)
+@NOTIFICATION_AREA_INPROCESS_FALSE@notification_area_applet_CFLAGS = $(AM_CFLAGS)
+BUILT_SOURCES = na-marshal.c na-marshal.h
+appletdir = $(datadir)/mate-panel/applets
+applet_in_files = org.mate.panel.NotificationAreaApplet.mate-panel-applet.in
+applet_DATA = $(applet_in_files:.mate-panel-applet.in=.mate-panel-applet)
+@NOTIFICATION_AREA_INPROCESS_FALSE@servicedir = $(datadir)/dbus-1/services
+@NOTIFICATION_AREA_INPROCESS_FALSE@service_in_files = org.mate.panel.applet.NotificationAreaAppletFactory.service.in
+@NOTIFICATION_AREA_INPROCESS_FALSE@service_DATA = $(service_in_files:.service.in=.service)
+uidir = $(datadir)/mate-panel/ui
+ui_DATA = notification-area-menu.xml
+EXTRA_DIST = \
+ org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in \
+ $(ui_DATA) \
+ $(service_in_files) \
+ na-marshal.list
+
+CLEANFILES = \
+ $(applet_DATA) \
+ $(applet_DATA).in \
+ $(service_DATA)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu applets/notification_area/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu applets/notification_area/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-notification_area_appletlibLTLIBRARIES: $(notification_area_appletlib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(notification_area_appletlibdir)" || $(MKDIR_P) "$(DESTDIR)$(notification_area_appletlibdir)"
+ @list='$(notification_area_appletlib_LTLIBRARIES)'; test -n "$(notification_area_appletlibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(notification_area_appletlibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(notification_area_appletlibdir)"; \
+ }
+
+uninstall-notification_area_appletlibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(notification_area_appletlib_LTLIBRARIES)'; test -n "$(notification_area_appletlibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(notification_area_appletlibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(notification_area_appletlibdir)/$$f"; \
+ done
+
+clean-notification_area_appletlibLTLIBRARIES:
+ -test -z "$(notification_area_appletlib_LTLIBRARIES)" || rm -f $(notification_area_appletlib_LTLIBRARIES)
+ @list='$(notification_area_appletlib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libnotification-area-applet.la: $(libnotification_area_applet_la_OBJECTS) $(libnotification_area_applet_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnotification_area_applet_la_LINK) $(am_libnotification_area_applet_la_rpath) $(libnotification_area_applet_la_OBJECTS) $(libnotification_area_applet_la_LIBADD) $(LIBS)
+libtray.la: $(libtray_la_OBJECTS) $(libtray_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libtray_la_OBJECTS) $(libtray_la_LIBADD) $(LIBS)
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+notification-area-applet$(EXEEXT): $(notification_area_applet_OBJECTS) $(notification_area_applet_DEPENDENCIES)
+ @rm -f notification-area-applet$(EXEEXT)
+ $(AM_V_CCLD)$(notification_area_applet_LINK) $(notification_area_applet_OBJECTS) $(notification_area_applet_LDADD) $(LIBS)
+testtray$(EXEEXT): $(testtray_OBJECTS) $(testtray_DEPENDENCIES)
+ @rm -f testtray$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testtray_OBJECTS) $(testtray_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixedtip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnotification_area_applet_la-main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/na-marshal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/na-tray-child.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/na-tray-manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/na-tray.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notification_area_applet-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testtray.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libnotification_area_applet_la-main.lo: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnotification_area_applet_la_CFLAGS) $(CFLAGS) -MT libnotification_area_applet_la-main.lo -MD -MP -MF $(DEPDIR)/libnotification_area_applet_la-main.Tpo -c -o libnotification_area_applet_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnotification_area_applet_la-main.Tpo $(DEPDIR)/libnotification_area_applet_la-main.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='libnotification_area_applet_la-main.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnotification_area_applet_la_CFLAGS) $(CFLAGS) -c -o libnotification_area_applet_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+notification_area_applet-main.o: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(notification_area_applet_CFLAGS) $(CFLAGS) -MT notification_area_applet-main.o -MD -MP -MF $(DEPDIR)/notification_area_applet-main.Tpo -c -o notification_area_applet-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/notification_area_applet-main.Tpo $(DEPDIR)/notification_area_applet-main.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='notification_area_applet-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(notification_area_applet_CFLAGS) $(CFLAGS) -c -o notification_area_applet-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+notification_area_applet-main.obj: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(notification_area_applet_CFLAGS) $(CFLAGS) -MT notification_area_applet-main.obj -MD -MP -MF $(DEPDIR)/notification_area_applet-main.Tpo -c -o notification_area_applet-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/notification_area_applet-main.Tpo $(DEPDIR)/notification_area_applet-main.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='notification_area_applet-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(notification_area_applet_CFLAGS) $(CFLAGS) -c -o notification_area_applet-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-appletDATA: $(applet_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(appletdir)" || $(MKDIR_P) "$(DESTDIR)$(appletdir)"
+ @list='$(applet_DATA)'; test -n "$(appletdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(appletdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(appletdir)" || exit $$?; \
+ done
+
+uninstall-appletDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(applet_DATA)'; test -n "$(appletdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(appletdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(appletdir)" && rm -f $$files
+install-serviceDATA: $(service_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(servicedir)" || $(MKDIR_P) "$(DESTDIR)$(servicedir)"
+ @list='$(service_DATA)'; test -n "$(servicedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(servicedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(servicedir)" || exit $$?; \
+ done
+
+uninstall-serviceDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(service_DATA)'; test -n "$(servicedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(servicedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(servicedir)" && rm -f $$files
+install-uiDATA: $(ui_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(uidir)" || $(MKDIR_P) "$(DESTDIR)$(uidir)"
+ @list='$(ui_DATA)'; test -n "$(uidir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(uidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(uidir)" || exit $$?; \
+ done
+
+uninstall-uiDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ui_DATA)'; test -n "$(uidir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(uidir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(uidir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(notification_area_appletlibdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(appletdir)" "$(DESTDIR)$(servicedir)" "$(DESTDIR)$(uidir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \
+ clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
+ clean-notification_area_appletlibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-appletDATA \
+ install-notification_area_appletlibLTLIBRARIES \
+ install-serviceDATA install-uiDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libexecPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-appletDATA uninstall-libexecPROGRAMS \
+ uninstall-notification_area_appletlibLTLIBRARIES \
+ uninstall-serviceDATA uninstall-uiDATA
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libexecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \
+ clean-noinstPROGRAMS \
+ clean-notification_area_appletlibLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-appletDATA install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libexecPROGRAMS install-man \
+ install-notification_area_appletlibLTLIBRARIES install-pdf \
+ install-pdf-am install-ps install-ps-am install-serviceDATA \
+ install-strip install-uiDATA installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-appletDATA uninstall-libexecPROGRAMS \
+ uninstall-notification_area_appletlibLTLIBRARIES \
+ uninstall-serviceDATA uninstall-uiDATA
+
+
+na-marshal.h: na-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN)$(GLIB_GENMARSHAL) $< --header --prefix=_na_marshal > $@
+
+na-marshal.c: na-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN)echo "#include \"na-marshal.h\"" > $@ && \
+ $(GLIB_GENMARSHAL) $< --body --prefix=_na_marshal >> $@
+
+$(applet_in_files): $(applet_in_files).in Makefile
+ $(AM_V_GEN)sed \
+ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+ -e "s|\@IN_PROCESS\@|$(APPLET_IN_PROCESS)|" \
+ -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \
+ $< > $@
+
+@PANEL_INTLTOOL_MATE_PANEL_APPLET_RULE@
+
+@NOTIFICATION_AREA_INPROCESS_FALSE@org.mate.panel.applet.NotificationAreaAppletFactory.service: $(service_in_files)
+@NOTIFICATION_AREA_INPROCESS_FALSE@ $(AM_V_GEN)sed \
+@NOTIFICATION_AREA_INPROCESS_FALSE@ -e "s|\@LOCATION\@|$(APPLET_LOCATION)|" \
+@NOTIFICATION_AREA_INPROCESS_FALSE@ $< > $@
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/applets/notification_area/fixedtip.c b/applets/notification_area/fixedtip.c
new file mode 100644
index 00000000..c32c6bf8
--- /dev/null
+++ b/applets/notification_area/fixedtip.c
@@ -0,0 +1,269 @@
+/* Marco fixed tooltip routine */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003-2006 Vincent Untz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "fixedtip.h"
+
+/* Signals */
+enum
+{
+ CLICKED,
+ LAST_SIGNAL
+};
+
+static guint fixedtip_signals[LAST_SIGNAL] = { 0 };
+
+struct _NaFixedTipPrivate
+{
+ GtkWidget *parent;
+ GtkWidget *label;
+ GtkOrientation orientation;
+};
+
+G_DEFINE_TYPE (NaFixedTip, na_fixed_tip, GTK_TYPE_WINDOW)
+
+static gboolean
+button_press_handler (GtkWidget *fixedtip,
+ GdkEventButton *event,
+ gpointer data)
+{
+ if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
+ g_signal_emit (fixedtip, fixedtip_signals[CLICKED], 0);
+
+ return FALSE;
+}
+
+static gboolean
+expose_handler (GtkWidget *fixedtip)
+{
+ GtkRequisition req;
+
+ gtk_widget_size_request (fixedtip, &req);
+
+ gtk_paint_flat_box (gtk_widget_get_style (fixedtip),
+ gtk_widget_get_window (fixedtip),
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, fixedtip, "tooltip",
+ 0, 0, req.width, req.height);
+
+ return FALSE;
+}
+
+static void
+na_fixed_tip_class_init (NaFixedTipClass *class)
+{
+ fixedtip_signals[CLICKED] =
+ g_signal_new ("clicked",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaFixedTipClass, clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (class, sizeof (NaFixedTipPrivate));
+}
+
+/* Did you already see this code? Yes, it's gtk_tooltips_ force_window() ;-) */
+static void
+na_fixed_tip_init (NaFixedTip *fixedtip)
+{
+ GtkWidget *label;
+
+ fixedtip->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixedtip, NA_TYPE_FIXED_TIP,
+ NaFixedTipPrivate);
+
+ gtk_window_set_type_hint (GTK_WINDOW (fixedtip),
+ GDK_WINDOW_TYPE_HINT_TOOLTIP);
+
+ gtk_widget_set_app_paintable (GTK_WIDGET (fixedtip), TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (fixedtip), FALSE);
+ gtk_widget_set_name (GTK_WIDGET (fixedtip), "gtk-tooltips");
+ gtk_container_set_border_width (GTK_CONTAINER (fixedtip), 4);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
+ gtk_widget_show (label);
+ gtk_container_add (GTK_CONTAINER (fixedtip), label);
+ fixedtip->priv->label = label;
+
+ g_signal_connect (fixedtip, "expose_event",
+ G_CALLBACK (expose_handler), NULL);
+
+ gtk_widget_add_events (GTK_WIDGET (fixedtip), GDK_BUTTON_PRESS_MASK);
+
+ g_signal_connect (fixedtip, "button_press_event",
+ G_CALLBACK (button_press_handler), NULL);
+
+ fixedtip->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+}
+
+static void
+na_fixed_tip_position (NaFixedTip *fixedtip)
+{
+ GdkScreen *screen;
+ GdkWindow *parent_window;
+ GtkRequisition req;
+ int root_x;
+ int root_y;
+ int parent_width;
+ int parent_height;
+ int screen_width;
+ int screen_height;
+
+ screen = gtk_widget_get_screen (fixedtip->priv->parent);
+ parent_window = gtk_widget_get_window (fixedtip->priv->parent);
+
+ gtk_window_set_screen (GTK_WINDOW (fixedtip), screen);
+
+ gtk_widget_size_request (GTK_WIDGET (fixedtip), &req);
+
+ gdk_window_get_origin (parent_window, &root_x, &root_y);
+ #if GTK_CHECK_VERSION(3, 0, 0)
+ parent_width = gdk_window_get_width(parent_window);
+ parent_height = gdk_window_get_height(parent_window);
+ #else
+ gdk_drawable_get_size(GDK_DRAWABLE(parent_window), &parent_width, &parent_height);
+ #endif
+
+
+ screen_width = gdk_screen_get_width (screen);
+ screen_height = gdk_screen_get_height (screen);
+
+ /* pad between panel and message window */
+#define PAD 5
+
+ if (fixedtip->priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ if (root_x <= screen_width / 2)
+ root_x += parent_width + PAD;
+ else
+ root_x -= req.width + PAD;
+ }
+ else
+ {
+ if (root_y <= screen_height / 2)
+ root_y += parent_height + PAD;
+ else
+ root_y -= req.height + PAD;
+ }
+
+ /* Push onscreen */
+ if ((root_x + req.width) > screen_width)
+ root_x = screen_width - req.width;
+
+ if ((root_y + req.height) > screen_height)
+ root_y = screen_height - req.height;
+
+ gtk_window_move (GTK_WINDOW (fixedtip), root_x, root_y);
+}
+
+static void
+na_fixed_tip_parent_size_allocated (GtkWidget *parent,
+ GtkAllocation *allocation,
+ NaFixedTip *fixedtip)
+{
+ na_fixed_tip_position (fixedtip);
+}
+
+static void
+na_fixed_tip_parent_screen_changed (GtkWidget *parent,
+ GdkScreen *new_screen,
+ NaFixedTip *fixedtip)
+{
+ na_fixed_tip_position (fixedtip);
+}
+
+GtkWidget *
+na_fixed_tip_new (GtkWidget *parent,
+ GtkOrientation orientation)
+{
+ NaFixedTip *fixedtip;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+
+ fixedtip = g_object_new (NA_TYPE_FIXED_TIP,
+ "type", GTK_WINDOW_POPUP,
+ NULL);
+
+ fixedtip->priv->parent = parent;
+
+#if 0
+ //FIXME: would be nice to be able to get the toplevel for the tip, but this
+ //doesn't work
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (parent);
+ /*
+ if (toplevel && gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
+ gtk_window_set_transient_for (GTK_WINDOW (fixedtip), GTK_WINDOW (toplevel));
+ */
+#endif
+
+ fixedtip->priv->orientation = orientation;
+
+ //FIXME: would be nice to move the tip when the notification area moves
+ g_signal_connect_object (parent, "size-allocate",
+ G_CALLBACK (na_fixed_tip_parent_size_allocated),
+ fixedtip, 0);
+ g_signal_connect_object (parent, "screen-changed",
+ G_CALLBACK (na_fixed_tip_parent_screen_changed),
+ fixedtip, 0);
+
+ na_fixed_tip_position (fixedtip);
+
+ return GTK_WIDGET (fixedtip);
+}
+
+void
+na_fixed_tip_set_markup (GtkWidget *widget,
+ const char *markup_text)
+{
+ NaFixedTip *fixedtip;
+
+ g_return_if_fail (NA_IS_FIXED_TIP (widget));
+
+ fixedtip = NA_FIXED_TIP (widget);
+
+ gtk_label_set_markup (GTK_LABEL (fixedtip->priv->label),
+ markup_text);
+
+ na_fixed_tip_position (fixedtip);
+}
+
+void
+na_fixed_tip_set_orientation (GtkWidget *widget,
+ GtkOrientation orientation)
+{
+ NaFixedTip *fixedtip;
+
+ g_return_if_fail (NA_IS_FIXED_TIP (widget));
+
+ fixedtip = NA_FIXED_TIP (widget);
+
+ if (orientation == fixedtip->priv->orientation)
+ return;
+
+ fixedtip->priv->orientation = orientation;
+
+ na_fixed_tip_position (fixedtip);
+}
diff --git a/applets/notification_area/fixedtip.h b/applets/notification_area/fixedtip.h
new file mode 100644
index 00000000..3b340c07
--- /dev/null
+++ b/applets/notification_area/fixedtip.h
@@ -0,0 +1,72 @@
+/* Fixed tooltip routine */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington, 2002 Red Hat Inc.
+ * Copyright (C) 2003-2006 Vincent Untz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef FIXED_TIP_H
+#define FIXED_TIP_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NA_TYPE_FIXED_TIP (na_fixed_tip_get_type ())
+#define NA_FIXED_TIP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_FIXED_TIP, NaFixedTip))
+#define NA_FIXED_TIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_FIXED_TIP, NaFixedTipClass))
+#define NA_IS_FIXED_TIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_FIXED_TIP))
+#define NA_IS_FIXED_TIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_FIXED_TIP))
+#define NA_FIXED_TIP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NA_TYPE_FIXED_TIP, NaFixedTipClass))
+
+typedef struct _NaFixedTip NaFixedTip;
+typedef struct _NaFixedTipPrivate NaFixedTipPrivate;
+typedef struct _NaFixedTipClass NaFixedTipClass;
+
+struct _NaFixedTip
+{
+ GtkWindow parent_instance;
+
+ NaFixedTipPrivate *priv;
+};
+
+struct _NaFixedTipClass
+{
+ GtkWindowClass parent_class;
+
+ void (* clicked) (NaFixedTip *fixedtip);
+};
+
+GType na_fixed_tip_get_type (void);
+
+GtkWidget *na_fixed_tip_new (GtkWidget *parent,
+ GtkOrientation orientation);
+
+void na_fixed_tip_set_markup (GtkWidget *widget,
+ const char *markup_text);
+
+void na_fixed_tip_set_orientation (GtkWidget *widget,
+ GtkOrientation orientation);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FIXED_TIP_H */
diff --git a/applets/notification_area/main.c b/applets/notification_area/main.c
new file mode 100644
index 00000000..fc11040f
--- /dev/null
+++ b/applets/notification_area/main.c
@@ -0,0 +1,267 @@
+/* System tray main() */
+
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2003-2006 Vincent Untz
+ * Copyright (C) 2011 Perberos
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <mate-panel-applet.h>
+#include <mate-panel-applet-mateconf.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "na-tray-manager.h"
+#include "na-tray.h"
+#include "fixedtip.h"
+
+#define NOTIFICATION_AREA_ICON "mate-panel-notification-area"
+
+typedef struct {
+ MatePanelApplet* applet;
+ NaTray* tray;
+} AppletData;
+
+static GtkOrientation get_orientation_from_applet(MatePanelApplet* applet)
+{
+ GtkOrientation orientation;
+
+ switch (mate_panel_applet_get_orient(applet))
+ {
+ case MATE_PANEL_APPLET_ORIENT_LEFT:
+ case MATE_PANEL_APPLET_ORIENT_RIGHT:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ break;
+ case MATE_PANEL_APPLET_ORIENT_UP:
+ case MATE_PANEL_APPLET_ORIENT_DOWN:
+ default:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ }
+
+ return orientation;
+}
+
+static void help_cb(GtkAction* action, AppletData* data)
+{
+ GError* error = NULL;
+ char* uri;
+ #define NA_HELP_DOC "user-guide"
+
+ uri = g_strdup_printf("ghelp:%s?%s", NA_HELP_DOC, "panels-notification-area");
+
+ gtk_show_uri(gtk_widget_get_screen(GTK_WIDGET(data->applet)), uri, gtk_get_current_event_time(), &error);
+
+ g_free(uri);
+
+ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_error_free(error);
+ }
+ else if(error)
+ {
+ GtkWidget* dialog;
+ char* primary;
+
+ primary = g_markup_printf_escaped (_("Could not display help document '%s'"), NA_HELP_DOC);
+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", primary);
+
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", error->message);
+
+ g_error_free(error);
+ g_free(primary);
+
+ g_signal_connect(dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), NOTIFICATION_AREA_ICON);
+ gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (GTK_WIDGET (data->applet)));
+ /* we have no parent window */
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Error displaying help document"));
+
+ gtk_widget_show (dialog);
+ }
+}
+
+static void about_cb(GtkAction* action, AppletData* data)
+{
+ const gchar* authors[] = {
+ "Havoc Pennington <[email protected]>",
+ "Anders Carlsson <[email protected]>",
+ "Vincent Untz <[email protected]>",
+ NULL
+ };
+
+ const char* documenters[] = {
+ "Sun GNOME Documentation Team <[email protected]>",
+ NULL
+ };
+
+ const char copyright[] = \
+ "Copyright \xc2\xa9 2002 Red Hat, Inc.\n"
+ "Copyright \xc2\xa9 2003-2006 Vincent Untz\n"
+ "Copyright \xc2\xa9 2011 Perberos";
+
+ gtk_show_about_dialog(NULL,
+ "program-name", _("Notification Area"),
+ "authors", authors,
+ //"comments", _(comments),
+ "copyright", copyright,
+ "documenters", documenters,
+ "logo-icon-name", NOTIFICATION_AREA_ICON,
+ "translator-credits", _("translator-credits"),
+ "version", VERSION,
+ "website", "http://matsusoft.com.ar/projects/mate/",
+ NULL);
+}
+
+static const GtkActionEntry menu_actions [] = {
+ { "SystemTrayHelp", GTK_STOCK_HELP, N_("_Help"),
+ NULL, NULL,
+ G_CALLBACK (help_cb) },
+ { "SystemTrayAbout", GTK_STOCK_ABOUT, N_("_About"),
+ NULL, NULL,
+ G_CALLBACK (about_cb) }
+};
+
+static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBackgroundType type, GdkColor* color, GdkPixmap* pixmap, AppletData* data)
+{
+ na_tray_force_redraw(data->tray);
+}
+
+
+static void applet_change_orientation(MatePanelApplet* applet, MatePanelAppletOrient orient, AppletData* data)
+{
+ na_tray_set_orientation(data->tray, get_orientation_from_applet(applet));
+}
+
+static void applet_destroy(MatePanelApplet* applet, AppletData* data)
+{
+}
+
+static void free_applet_data(AppletData* data)
+{
+ g_slice_free(AppletData, data);
+}
+
+static void on_applet_realized(GtkWidget* widget, gpointer user_data)
+{
+ MatePanelApplet* applet;
+ AppletData* data;
+ NaTray* tray;
+ GtkActionGroup* action_group;
+ gchar* ui_path;
+
+ applet = MATE_PANEL_APPLET(widget);
+ data = g_object_get_data(G_OBJECT(widget), "system-tray-data");
+
+ if (data != NULL)
+ {
+ return;
+ }
+
+ tray = na_tray_new_for_screen(gtk_widget_get_screen(GTK_WIDGET(applet)), get_orientation_from_applet(applet));
+
+ data = g_slice_new(AppletData);
+ data->applet = applet;
+ data->tray = tray;
+
+ g_object_set_data_full(G_OBJECT(applet), "system-tray-data", data, (GDestroyNotify) free_applet_data);
+
+ g_signal_connect(applet, "change_orient", G_CALLBACK (applet_change_orientation), data);
+ g_signal_connect(applet, "change_background", G_CALLBACK (applet_change_background), data);
+ g_signal_connect(applet, "destroy", G_CALLBACK (applet_destroy), data);
+
+ gtk_container_add(GTK_CONTAINER (applet), GTK_WIDGET (tray));
+ gtk_widget_show(GTK_WIDGET(tray));
+
+ action_group = gtk_action_group_new("ClockApplet Menu Actions");
+ gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions(action_group, menu_actions, G_N_ELEMENTS(menu_actions), data);
+ ui_path = g_build_filename(NOTIFICATION_AREA_MENU_UI_DIR, "notification-area-menu.xml", NULL);
+ mate_panel_applet_setup_menu_from_file(applet, ui_path, action_group);
+ g_free(ui_path);
+ g_object_unref(action_group);
+
+}
+
+static inline void force_no_focus_padding(GtkWidget* widget)
+{
+ static gboolean first_time = TRUE;
+
+ if (first_time)
+ {
+ gtk_rc_parse_string ("\n"
+ " style \"na-tray-style\"\n"
+ " {\n"
+ " GtkWidget::focus-line-width=0\n"
+ " GtkWidget::focus-padding=0\n"
+ " }\n"
+ "\n"
+ " widget \"*.PanelAppletNaTray\" style \"na-tray-style\"\n"
+ "\n");
+
+ first_time = FALSE;
+ }
+
+ /* El widget antes se llamaba na-tray
+ *
+ * Issue #27
+ */
+ gtk_widget_set_name(widget, "PanelAppletNaTray");
+}
+
+static gboolean applet_factory(MatePanelApplet* applet, const gchar* iid, gpointer user_data)
+{
+ AtkObject* atko;
+
+ if (!(strcmp (iid, "NotificationArea") == 0 || strcmp (iid, "SystemTrayApplet") == 0))
+ {
+ return FALSE;
+ }
+
+ /* Defer loading until applet is added to panel so
+ * gtk_widget_get_screen returns correct information */
+ g_signal_connect(GTK_WIDGET(applet), "realize", G_CALLBACK(on_applet_realized), NULL);
+
+ atko = gtk_widget_get_accessible (GTK_WIDGET (applet));
+ atk_object_set_name (atko, _("Panel Notification Area"));
+
+ mate_panel_applet_set_flags(applet, MATE_PANEL_APPLET_HAS_HANDLE | MATE_PANEL_APPLET_EXPAND_MINOR);
+
+ mate_panel_applet_set_background_widget(applet, GTK_WIDGET(applet));
+
+ force_no_focus_padding(GTK_WIDGET(applet));
+
+ #ifndef NOTIFICATION_AREA_INPROCESS
+ gtk_window_set_default_icon_name(NOTIFICATION_AREA_ICON);
+ #endif
+
+ gtk_widget_show_all(GTK_WIDGET(applet));
+ return TRUE;
+}
+
+#ifdef NOTIFICATION_AREA_INPROCESS
+ MATE_PANEL_APPLET_IN_PROCESS_FACTORY("NotificationAreaAppletFactory", PANEL_TYPE_APPLET, "NotificationArea", applet_factory, NULL)
+#else
+ MATE_PANEL_APPLET_OUT_PROCESS_FACTORY("NotificationAreaAppletFactory", PANEL_TYPE_APPLET, "NotificationArea", applet_factory, NULL)
+#endif
diff --git a/applets/notification_area/na-marshal.c b/applets/notification_area/na-marshal.c
new file mode 100644
index 00000000..1f3c2020
--- /dev/null
+++ b/applets/notification_area/na-marshal.c
@@ -0,0 +1,167 @@
+#include "na-marshal.h"
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:OBJECT,OBJECT (na-marshal.list:1) */
+void
+_na_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__OBJECT_OBJECT callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_object (param_values + 1),
+ g_marshal_value_peek_object (param_values + 2),
+ data2);
+}
+
+/* VOID:OBJECT,STRING,LONG,LONG (na-marshal.list:2) */
+void
+_na_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ glong arg_3,
+ glong arg_4,
+ gpointer data2);
+ register GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 5);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_object (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ g_marshal_value_peek_long (param_values + 3),
+ g_marshal_value_peek_long (param_values + 4),
+ data2);
+}
+
+/* VOID:OBJECT,LONG (na-marshal.list:3) */
+void
+_na_marshal_VOID__OBJECT_LONG (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__OBJECT_LONG) (gpointer data1,
+ gpointer arg_1,
+ glong arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__OBJECT_LONG callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__OBJECT_LONG) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_object (param_values + 1),
+ g_marshal_value_peek_long (param_values + 2),
+ data2);
+}
+
diff --git a/applets/notification_area/na-marshal.h b/applets/notification_area/na-marshal.h
new file mode 100644
index 00000000..07918a11
--- /dev/null
+++ b/applets/notification_area/na-marshal.h
@@ -0,0 +1,36 @@
+
+#ifndef ___na_marshal_MARSHAL_H__
+#define ___na_marshal_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* VOID:OBJECT,OBJECT (na-marshal.list:1) */
+extern void _na_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:OBJECT,STRING,LONG,LONG (na-marshal.list:2) */
+extern void _na_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:OBJECT,LONG (na-marshal.list:3) */
+extern void _na_marshal_VOID__OBJECT_LONG (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+G_END_DECLS
+
+#endif /* ___na_marshal_MARSHAL_H__ */
+
diff --git a/applets/notification_area/na-marshal.list b/applets/notification_area/na-marshal.list
new file mode 100644
index 00000000..e3fc3993
--- /dev/null
+++ b/applets/notification_area/na-marshal.list
@@ -0,0 +1,3 @@
+VOID:OBJECT,OBJECT
+VOID:OBJECT,STRING,LONG,LONG
+VOID:OBJECT,LONG
diff --git a/applets/notification_area/na-tray-child.c b/applets/notification_area/na-tray-child.c
new file mode 100644
index 00000000..b946386b
--- /dev/null
+++ b/applets/notification_area/na-tray-child.c
@@ -0,0 +1,539 @@
+/* na-tray-child.c
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include "na-tray-child.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+G_DEFINE_TYPE (NaTrayChild, na_tray_child, GTK_TYPE_SOCKET)
+
+static void
+na_tray_child_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (na_tray_child_parent_class)->finalize (object);
+}
+
+static void
+na_tray_child_realize (GtkWidget *widget)
+{
+ NaTrayChild *child = NA_TRAY_CHILD (widget);
+ GdkVisual *visual = gtk_widget_get_visual (widget);
+ GdkWindow *window;
+
+ GTK_WIDGET_CLASS (na_tray_child_parent_class)->realize (widget);
+
+ window = gtk_widget_get_window (widget);
+
+ if (child->has_alpha)
+ {
+ /* We have real transparency with an ARGB visual and the Composite
+ * extension. */
+
+ /* Set a transparent background */
+ GdkColor transparent = { 0, 0, 0, 0 }; /* only pixel=0 matters */
+ gdk_window_set_background (window, &transparent);
+ gdk_window_set_composited (window, TRUE);
+
+ child->parent_relative_bg = FALSE;
+ }
+ #if GTK_CHECK_VERSION(3, 0, 0)
+ else if (visual == gdk_window_get_visual(gdk_window_get_parent(window)))
+ #else
+ else if (visual == gdk_drawable_get_visual(GDK_DRAWABLE(gdk_window_get_parent(window))))
+ #endif
+ {
+ /* Otherwise, if the visual matches the visual of the parent window, we
+ * can use a parent-relative background and fake transparency. */
+ gdk_window_set_back_pixmap (window, NULL, TRUE);
+
+ child->parent_relative_bg = TRUE;
+ }
+ else
+ {
+ /* Nothing to do; the icon will sit on top of an ugly gray box */
+ child->parent_relative_bg = FALSE;
+ }
+
+ gdk_window_set_composited (window, child->composited);
+
+ gtk_widget_set_app_paintable (GTK_WIDGET (child),
+ child->parent_relative_bg || child->has_alpha);
+
+ /* Double-buffering will interfere with the parent-relative-background fake
+ * transparency, since the double-buffer code doesn't know how to fill in the
+ * background of the double-buffer correctly.
+ */
+ gtk_widget_set_double_buffered (GTK_WIDGET (child),
+ child->parent_relative_bg);
+}
+
+static void
+na_tray_child_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ /* The default handler resets the background according to the new style.
+ * We either use a transparent background or a parent-relative background
+ * and ignore the style background. So, just don't chain up.
+ */
+}
+
+#if 0
+/* This is adapted from code that was commented out in na-tray-manager.c; the
+ * code in na-tray-manager.c wouldn't have worked reliably, this will. So maybe
+ * it can be reenabled. On other hand, things seem to be working fine without
+ * it.
+ *
+ * If reenabling, you need to hook it up in na_tray_child_class_init().
+ */
+static void
+na_tray_child_size_request (GtkWidget *widget,
+ GtkRequisition *request)
+{
+ GTK_WIDGET_CLASS (na_tray_child_parent_class)->size_request (widget, request);
+
+ /*
+ * Make sure the icons have a meaningful size ..
+ */
+ if ((request->width < 16) || (request->height < 16))
+ {
+ gint nw = MAX (24, request->width);
+ gint nh = MAX (24, request->height);
+ g_warning ("Tray icon has requested a size of (%ix%i), resizing to (%ix%i)",
+ req.width, req.height, nw, nh);
+ request->width = nw;
+ request->height = nh;
+ }
+}
+#endif
+
+static void
+na_tray_child_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ NaTrayChild *child = NA_TRAY_CHILD (widget);
+ GtkAllocation widget_allocation;
+ gboolean moved, resized;
+
+ gtk_widget_get_allocation (widget, &widget_allocation);
+
+ moved = (allocation->x != widget_allocation.x ||
+ allocation->y != widget_allocation.y);
+ resized = (allocation->width != widget_allocation.width ||
+ allocation->height != widget_allocation.height);
+
+ /* When we are allocating the widget while mapped we need special handling
+ * for both real and fake transparency.
+ *
+ * Real transparency: we need to invalidate and trigger a redraw of the old
+ * and new areas. (GDK really should handle this for us, but doesn't as of
+ * GTK+-2.14)
+ *
+ * Fake transparency: if the widget moved, we need to force the contents to
+ * be redrawn with the new offset for the parent-relative background.
+ */
+ if ((moved || resized) && gtk_widget_get_mapped (widget))
+ {
+ if (na_tray_child_has_alpha (child))
+ gdk_window_invalidate_rect (gdk_window_get_parent (gtk_widget_get_window (widget)),
+ &widget_allocation, FALSE);
+ }
+
+ GTK_WIDGET_CLASS (na_tray_child_parent_class)->size_allocate (widget,
+ allocation);
+
+ if ((moved || resized) && gtk_widget_get_mapped (widget))
+ {
+ if (na_tray_child_has_alpha (NA_TRAY_CHILD (widget)))
+ gdk_window_invalidate_rect (gdk_window_get_parent (gtk_widget_get_window (widget)),
+ &widget_allocation, FALSE);
+ else if (moved && child->parent_relative_bg)
+ na_tray_child_force_redraw (child);
+ }
+}
+
+/* The plug window should completely occupy the area of the child, so we won't
+ * get an expose event. But in case we do (the plug unmaps itself, say), this
+ * expose handler draws with real or fake transparency.
+ */
+static gboolean
+na_tray_child_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ NaTrayChild *child = NA_TRAY_CHILD (widget);
+ GdkWindow *window = gtk_widget_get_window (widget);
+
+ if (na_tray_child_has_alpha (child))
+ {
+ /* Clear to transparent */
+ cairo_t *cr = gdk_cairo_create (window);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ gdk_cairo_region (cr, event->region);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ }
+ else if (child->parent_relative_bg)
+ {
+ /* Clear to parent-relative pixmap */
+ gdk_window_clear_area (window,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ }
+
+ return FALSE;
+}
+
+static void
+na_tray_child_init (NaTrayChild *child)
+{
+}
+
+static void
+na_tray_child_class_init (NaTrayChildClass *klass)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *widget_class;
+
+ gobject_class = (GObjectClass *)klass;
+ widget_class = (GtkWidgetClass *)klass;
+
+ gobject_class->finalize = na_tray_child_finalize;
+ widget_class->style_set = na_tray_child_style_set;
+ widget_class->realize = na_tray_child_realize;
+ widget_class->size_allocate = na_tray_child_size_allocate;
+ widget_class->expose_event = na_tray_child_expose_event;
+}
+
+GtkWidget *
+na_tray_child_new (GdkScreen *screen,
+ Window icon_window)
+{
+ XWindowAttributes window_attributes;
+ Display *xdisplay;
+ NaTrayChild *child;
+ GdkVisual *visual;
+ gboolean visual_has_alpha;
+ GdkColormap *colormap;
+ gboolean new_colormap;
+ int red_prec, green_prec, blue_prec, depth;
+ int result;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+ g_return_val_if_fail (icon_window != None, NULL);
+
+ xdisplay = GDK_SCREEN_XDISPLAY (screen);
+
+ /* We need to determine the visual of the window we are embedding and create
+ * the socket in the same visual.
+ */
+
+ gdk_error_trap_push ();
+ result = XGetWindowAttributes (xdisplay, icon_window,
+ &window_attributes);
+ gdk_error_trap_pop ();
+
+ if (!result) /* Window already gone */
+ return NULL;
+
+ visual = gdk_x11_screen_lookup_visual (screen,
+ window_attributes.visual->visualid);
+ if (!visual) /* Icon window is on another screen? */
+ return NULL;
+
+ new_colormap = FALSE;
+
+ if (visual == gdk_screen_get_rgb_visual (screen))
+ colormap = gdk_screen_get_rgb_colormap (screen);
+ else if (visual == gdk_screen_get_rgba_visual (screen))
+ colormap = gdk_screen_get_rgba_colormap (screen);
+ else if (visual == gdk_screen_get_system_visual (screen))
+ colormap = gdk_screen_get_system_colormap (screen);
+ else
+ {
+ colormap = gdk_colormap_new (visual, FALSE);
+ new_colormap = TRUE;
+ }
+
+ child = g_object_new (NA_TYPE_TRAY_CHILD, NULL);
+ child->icon_window = icon_window;
+
+ gtk_widget_set_colormap (GTK_WIDGET (child), colormap);
+
+ /* We have alpha if the visual has something other than red, green,
+ * and blue */
+ gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec);
+ gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec);
+ gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec);
+ depth = gdk_visual_get_depth (visual);
+
+ visual_has_alpha = red_prec + blue_prec + green_prec < depth;
+ child->has_alpha = (visual_has_alpha &&
+ gdk_display_supports_composite (gdk_screen_get_display (screen)));
+
+ child->composited = child->has_alpha;
+
+ if (new_colormap)
+ g_object_unref (colormap);
+
+ return GTK_WIDGET (child);
+}
+
+char *
+na_tray_child_get_title (NaTrayChild *child)
+{
+ char *retval = NULL;
+ GdkDisplay *display;
+ Atom utf8_string, atom, type;
+ int result;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ gchar *val;
+
+ g_return_val_if_fail (NA_IS_TRAY_CHILD (child), NULL);
+
+ display = gtk_widget_get_display (GTK_WIDGET (child));
+
+ utf8_string = gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING");
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME");
+
+ gdk_error_trap_push ();
+
+ result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ child->icon_window,
+ atom,
+ 0, G_MAXLONG,
+ False, utf8_string,
+ &type, &format, &nitems,
+ &bytes_after, (guchar **)&val);
+
+ if (gdk_error_trap_pop () || result != Success)
+ return NULL;
+
+ if (type != utf8_string ||
+ format != 8 ||
+ nitems == 0)
+ {
+ if (val)
+ XFree (val);
+ return NULL;
+ }
+
+ if (!g_utf8_validate (val, nitems, NULL))
+ {
+ XFree (val);
+ return NULL;
+ }
+
+ retval = g_strndup (val, nitems);
+
+ XFree (val);
+
+ return retval;
+}
+
+/**
+ * na_tray_child_has_alpha;
+ * @child: a #NaTrayChild
+ *
+ * Checks if the child has an ARGB visual and real alpha transparence.
+ * (as opposed to faked alpha transparency with an parent-relative
+ * background)
+ *
+ * Return value: %TRUE if the child has an alpha transparency
+ */
+gboolean
+na_tray_child_has_alpha (NaTrayChild *child)
+{
+ g_return_val_if_fail (NA_IS_TRAY_CHILD (child), FALSE);
+
+ return child->has_alpha;
+}
+
+/**
+ * na_tray_child_set_composited;
+ * @child: a #NaTrayChild
+ * @composited: %TRUE if the child's window should be redirected
+ *
+ * Sets whether the #GdkWindow of the child should be set redirected
+ * using gdk_window_set_composited(). By default this is based off of
+ * na_tray_child_has_alpha(), but it may be useful to override it in
+ * certain circumstances; for example, if the #NaTrayChild is added
+ * to a parent window and that parent window is composited against the
+ * background.
+ */
+void
+na_tray_child_set_composited (NaTrayChild *child,
+ gboolean composited)
+{
+ g_return_if_fail (NA_IS_TRAY_CHILD (child));
+
+ if (child->composited == composited)
+ return;
+
+ child->composited = composited;
+ if (gtk_widget_get_realized (GTK_WIDGET (child)))
+ gdk_window_set_composited (gtk_widget_get_window (GTK_WIDGET (child)),
+ composited);
+}
+
+/* If we are faking transparency with a window-relative background, force a
+ * redraw of the icon. This should be called if the background changes or if
+ * the child is shifted with respect to the background.
+ */
+void
+na_tray_child_force_redraw (NaTrayChild *child)
+{
+ GtkWidget *widget = GTK_WIDGET (child);
+
+ if (gtk_widget_get_mapped (widget) && child->parent_relative_bg)
+ {
+#if 1
+ /* Sending an ExposeEvent might cause redraw problems if the
+ * icon is expecting the server to clear-to-background before
+ * the redraw. It should be ok for GtkStatusIcon or EggTrayIcon.
+ */
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
+ XEvent xev;
+ GdkWindow *plug_window;
+ GtkAllocation allocation;
+
+ plug_window = gtk_socket_get_plug_window (GTK_SOCKET (child));
+ gtk_widget_get_allocation (widget, &allocation);
+
+ xev.xexpose.type = Expose;
+ xev.xexpose.window = GDK_WINDOW_XWINDOW (plug_window);
+ xev.xexpose.x = 0;
+ xev.xexpose.y = 0;
+ xev.xexpose.width = allocation.width;
+ xev.xexpose.height = allocation.height;
+ xev.xexpose.count = 0;
+
+ gdk_error_trap_push ();
+ XSendEvent (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
+ xev.xexpose.window,
+ False, ExposureMask,
+ &xev);
+ /* We have to sync to reliably catch errors from the XSendEvent(),
+ * since that is asynchronous.
+ */
+ XSync (xdisplay, False);
+ gdk_error_trap_pop ();
+#else
+ /* Hiding and showing is the safe way to do it, but can result in more
+ * flickering.
+ */
+ gdk_window_hide (widget->window);
+ gdk_window_show (widget->window);
+#endif
+ }
+}
+
+/* from libwnck/xutils.c, comes as LGPLv2+ */
+static char *
+latin1_to_utf8 (const char *latin1)
+{
+ GString *str;
+ const char *p;
+
+ str = g_string_new (NULL);
+
+ p = latin1;
+ while (*p)
+ {
+ g_string_append_unichar (str, (gunichar) *p);
+ ++p;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+/* derived from libwnck/xutils.c, comes as LGPLv2+ */
+static void
+_get_wmclass (Display *xdisplay,
+ Window xwindow,
+ char **res_class,
+ char **res_name)
+{
+ XClassHint ch;
+
+ ch.res_name = NULL;
+ ch.res_class = NULL;
+
+ gdk_error_trap_push ();
+ XGetClassHint (xdisplay, xwindow, &ch);
+ gdk_error_trap_pop ();
+
+ if (res_class)
+ *res_class = NULL;
+
+ if (res_name)
+ *res_name = NULL;
+
+ if (ch.res_name)
+ {
+ if (res_name)
+ *res_name = latin1_to_utf8 (ch.res_name);
+
+ XFree (ch.res_name);
+ }
+
+ if (ch.res_class)
+ {
+ if (res_class)
+ *res_class = latin1_to_utf8 (ch.res_class);
+
+ XFree (ch.res_class);
+ }
+}
+
+/**
+ * na_tray_child_get_wm_class;
+ * @child: a #NaTrayChild
+ * @res_name: return location for a string containing the application name of
+ * @child, or %NULL
+ * @res_class: return location for a string containing the application class of
+ * @child, or %NULL
+ *
+ * Fetches the resource associated with @child.
+ */
+void
+na_tray_child_get_wm_class (NaTrayChild *child,
+ char **res_name,
+ char **res_class)
+{
+ GdkDisplay *display;
+
+ g_return_if_fail (NA_IS_TRAY_CHILD (child));
+
+ display = gtk_widget_get_display (GTK_WIDGET (child));
+
+ _get_wmclass (GDK_DISPLAY_XDISPLAY (display),
+ child->icon_window,
+ res_class,
+ res_name);
+}
diff --git a/applets/notification_area/na-tray-child.h b/applets/notification_area/na-tray-child.h
new file mode 100644
index 00000000..735770ac
--- /dev/null
+++ b/applets/notification_area/na-tray-child.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* na-tray-child.h
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __NA_TRAY_CHILD_H__
+#define __NA_TRAY_CHILD_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NA_TYPE_TRAY_CHILD (na_tray_child_get_type ())
+#define NA_TRAY_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_TRAY_CHILD, NaTrayChild))
+#define NA_TRAY_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_TRAY_CHILD, NaTrayChildClass))
+#define NA_IS_TRAY_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_TRAY_CHILD))
+#define NA_IS_TRAY_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_TRAY_CHILD))
+#define NA_TRAY_CHILD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NA_TYPE_TRAY_CHILD, NaTrayChildClass))
+
+typedef struct _NaTrayChild NaTrayChild;
+typedef struct _NaTrayChildClass NaTrayChildClass;
+typedef struct _NaTrayChildChild NaTrayChildChild;
+
+struct _NaTrayChild
+{
+ GtkSocket parent_instance;
+ Window icon_window;
+ guint has_alpha : 1;
+ guint composited : 1;
+ guint parent_relative_bg : 1;
+};
+
+struct _NaTrayChildClass
+{
+ GtkSocketClass parent_class;
+};
+
+GType na_tray_child_get_type (void);
+
+GtkWidget *na_tray_child_new (GdkScreen *screen,
+ Window icon_window);
+char *na_tray_child_get_title (NaTrayChild *child);
+gboolean na_tray_child_has_alpha (NaTrayChild *child);
+void na_tray_child_set_composited (NaTrayChild *child,
+ gboolean composited);
+void na_tray_child_force_redraw (NaTrayChild *child);
+void na_tray_child_get_wm_class (NaTrayChild *child,
+ char **res_name,
+ char **res_class);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NA_TRAY_CHILD_H__ */
diff --git a/applets/notification_area/na-tray-manager.c b/applets/notification_area/na-tray-manager.c
new file mode 100644
index 00000000..1c582a62
--- /dev/null
+++ b/applets/notification_area/na-tray-manager.c
@@ -0,0 +1,859 @@
+/* na-tray-manager.c
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Used to be: eggtraymanager.c
+ */
+
+#include <config.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "na-tray-manager.h"
+
+#include <gdkconfig.h>
+#include <glib/gi18n.h>
+#if defined (GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+#elif defined (GDK_WINDOWING_WIN32)
+#include <gdk/gdkwin32.h>
+#endif
+#include <gtk/gtk.h>
+
+#include "na-marshal.h"
+
+/* Signals */
+enum
+{
+ TRAY_ICON_ADDED,
+ TRAY_ICON_REMOVED,
+ MESSAGE_SENT,
+ MESSAGE_CANCELLED,
+ LOST_SELECTION,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_ORIENTATION
+};
+
+typedef struct
+{
+ long id, len;
+ long remaining_len;
+
+ long timeout;
+ char *str;
+#ifdef GDK_WINDOWING_X11
+ Window window;
+#endif
+} PendingMessage;
+
+static guint manager_signals[LAST_SIGNAL];
+
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+#define SYSTEM_TRAY_BEGIN_MESSAGE 1
+#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+
+#define SYSTEM_TRAY_ORIENTATION_HORZ 0
+#define SYSTEM_TRAY_ORIENTATION_VERT 1
+
+#ifdef GDK_WINDOWING_X11
+static gboolean na_tray_manager_check_running_screen_x11 (GdkScreen *screen);
+#endif
+
+static void na_tray_manager_finalize (GObject *object);
+static void na_tray_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void na_tray_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void na_tray_manager_unmanage (NaTrayManager *manager);
+
+G_DEFINE_TYPE (NaTrayManager, na_tray_manager, G_TYPE_OBJECT)
+
+static void
+na_tray_manager_init (NaTrayManager *manager)
+{
+ manager->invisible = NULL;
+ manager->socket_table = g_hash_table_new (NULL, NULL);
+}
+
+static void
+na_tray_manager_class_init (NaTrayManagerClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = (GObjectClass *)klass;
+
+ gobject_class->finalize = na_tray_manager_finalize;
+ gobject_class->set_property = na_tray_manager_set_property;
+ gobject_class->get_property = na_tray_manager_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ORIENTATION,
+ g_param_spec_enum ("orientation",
+ "orientation",
+ "orientation",
+ GTK_TYPE_ORIENTATION,
+ GTK_ORIENTATION_HORIZONTAL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ manager_signals[TRAY_ICON_ADDED] =
+ g_signal_new ("tray_icon_added",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaTrayManagerClass, tray_icon_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_SOCKET);
+
+ manager_signals[TRAY_ICON_REMOVED] =
+ g_signal_new ("tray_icon_removed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaTrayManagerClass, tray_icon_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_SOCKET);
+ manager_signals[MESSAGE_SENT] =
+ g_signal_new ("message_sent",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaTrayManagerClass, message_sent),
+ NULL, NULL,
+ _na_marshal_VOID__OBJECT_STRING_LONG_LONG,
+ G_TYPE_NONE, 4,
+ GTK_TYPE_SOCKET,
+ G_TYPE_STRING,
+ G_TYPE_LONG,
+ G_TYPE_LONG);
+ manager_signals[MESSAGE_CANCELLED] =
+ g_signal_new ("message_cancelled",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaTrayManagerClass, message_cancelled),
+ NULL, NULL,
+ _na_marshal_VOID__OBJECT_LONG,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_SOCKET,
+ G_TYPE_LONG);
+ manager_signals[LOST_SELECTION] =
+ g_signal_new ("lost_selection",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NaTrayManagerClass, lost_selection),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+#if defined (GDK_WINDOWING_X11)
+ /* Nothing */
+#elif defined (GDK_WINDOWING_WIN32)
+ g_warning ("Port NaTrayManager to Win32");
+#else
+ g_warning ("Port NaTrayManager to this GTK+ backend");
+#endif
+}
+
+static void
+na_tray_manager_finalize (GObject *object)
+{
+ NaTrayManager *manager;
+
+ manager = NA_TRAY_MANAGER (object);
+
+ na_tray_manager_unmanage (manager);
+
+ g_list_free (manager->messages);
+ g_hash_table_destroy (manager->socket_table);
+
+ G_OBJECT_CLASS (na_tray_manager_parent_class)->finalize (object);
+}
+
+static void
+na_tray_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ NaTrayManager *manager = NA_TRAY_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ na_tray_manager_set_orientation (manager, g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+na_tray_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NaTrayManager *manager = NA_TRAY_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, manager->orientation);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+NaTrayManager *
+na_tray_manager_new (void)
+{
+ NaTrayManager *manager;
+
+ manager = g_object_new (NA_TYPE_TRAY_MANAGER, NULL);
+
+ return manager;
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static gboolean
+na_tray_manager_plug_removed (GtkSocket *socket,
+ NaTrayManager *manager)
+{
+ NaTrayChild *child = NA_TRAY_CHILD (socket);
+
+ g_hash_table_remove (manager->socket_table,
+ GINT_TO_POINTER (child->icon_window));
+ g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, child);
+
+ /* This destroys the socket. */
+ return FALSE;
+}
+
+static void
+na_tray_manager_handle_dock_request (NaTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ Window icon_window = xevent->data.l[2];
+ GtkWidget *child;
+
+ if (g_hash_table_lookup (manager->socket_table,
+ GINT_TO_POINTER (icon_window)))
+ {
+ /* We already got this notification earlier, ignore this one */
+ return;
+ }
+
+ child = na_tray_child_new (manager->screen, icon_window);
+ if (child == NULL) /* already gone or other error */
+ return;
+
+ g_signal_emit (manager, manager_signals[TRAY_ICON_ADDED], 0,
+ child);
+
+ /* If the child wasn't attached, then destroy it */
+
+ if (!GTK_IS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (child))))
+ {
+ gtk_widget_destroy (child);
+ return;
+ }
+
+ g_signal_connect (child, "plug_removed",
+ G_CALLBACK (na_tray_manager_plug_removed), manager);
+
+ gtk_socket_add_id (GTK_SOCKET (child), icon_window);
+
+ if (!gtk_socket_get_plug_window (GTK_SOCKET (child)))
+ {
+ /* Embedding failed, we won't get a plug-removed signal */
+ g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, child);
+ gtk_widget_destroy (child);
+ return;
+ }
+
+ g_hash_table_insert (manager->socket_table,
+ GINT_TO_POINTER (icon_window), child);
+ gtk_widget_show (child);
+}
+
+static void
+pending_message_free (PendingMessage *message)
+{
+ g_free (message->str);
+ g_free (message);
+}
+
+static GdkFilterReturn
+na_tray_manager_handle_client_message_message_data (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer data)
+{
+ XClientMessageEvent *xevent;
+ NaTrayManager *manager;
+ GList *p;
+ int len;
+
+ xevent = (XClientMessageEvent *) xev;
+ manager = data;
+
+ /* Try to see if we can find the pending message in the list */
+ for (p = manager->messages; p; p = p->next)
+ {
+ PendingMessage *msg = p->data;
+
+ if (xevent->window == msg->window)
+ {
+ /* Append the message */
+ len = MIN (msg->remaining_len, 20);
+
+ memcpy ((msg->str + msg->len - msg->remaining_len),
+ &xevent->data, len);
+ msg->remaining_len -= len;
+
+ if (msg->remaining_len == 0)
+ {
+ GtkSocket *socket;
+
+ socket = g_hash_table_lookup (manager->socket_table,
+ GINT_TO_POINTER (msg->window));
+
+ if (socket)
+ g_signal_emit (manager, manager_signals[MESSAGE_SENT], 0,
+ socket, msg->str, msg->id, msg->timeout);
+
+ pending_message_free (msg);
+ manager->messages = g_list_remove_link (manager->messages, p);
+ g_list_free_1 (p);
+ }
+
+ break;
+ }
+ }
+
+ return GDK_FILTER_REMOVE;
+}
+
+static void
+na_tray_manager_handle_begin_message (NaTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkSocket *socket;
+ GList *p;
+ PendingMessage *msg;
+ long timeout;
+ long len;
+ long id;
+
+ socket = g_hash_table_lookup (manager->socket_table,
+ GINT_TO_POINTER (xevent->window));
+ /* we don't know about this tray icon, so ignore the message */
+ if (!socket)
+ return;
+
+ /* Check if the same message is already in the queue and remove it if so */
+ for (p = manager->messages; p; p = p->next)
+ {
+ PendingMessage *pmsg = p->data;
+
+ if (xevent->window == pmsg->window &&
+ xevent->data.l[4] == pmsg->id)
+ {
+ /* Hmm, we found it, now remove it */
+ pending_message_free (pmsg);
+ manager->messages = g_list_remove_link (manager->messages, p);
+ g_list_free_1 (p);
+ break;
+ }
+ }
+
+ timeout = xevent->data.l[2];
+ len = xevent->data.l[3];
+ id = xevent->data.l[4];
+
+ if (len == 0)
+ {
+ g_signal_emit (manager, manager_signals[MESSAGE_SENT], 0,
+ socket, "", id, timeout);
+ }
+ else
+ {
+ /* Now add the new message to the queue */
+ msg = g_new0 (PendingMessage, 1);
+ msg->window = xevent->window;
+ msg->timeout = timeout;
+ msg->len = len;
+ msg->id = id;
+ msg->remaining_len = msg->len;
+ msg->str = g_malloc (msg->len + 1);
+ msg->str[msg->len] = '\0';
+ manager->messages = g_list_prepend (manager->messages, msg);
+ }
+}
+
+static void
+na_tray_manager_handle_cancel_message (NaTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GList *p;
+ GtkSocket *socket;
+
+ /* Check if the message is in the queue and remove it if so */
+ for (p = manager->messages; p; p = p->next)
+ {
+ PendingMessage *msg = p->data;
+
+ if (xevent->window == msg->window &&
+ xevent->data.l[4] == msg->id)
+ {
+ pending_message_free (msg);
+ manager->messages = g_list_remove_link (manager->messages, p);
+ g_list_free_1 (p);
+ break;
+ }
+ }
+
+ socket = g_hash_table_lookup (manager->socket_table,
+ GINT_TO_POINTER (xevent->window));
+
+ if (socket)
+ {
+ g_signal_emit (manager, manager_signals[MESSAGE_CANCELLED], 0,
+ socket, xevent->data.l[2]);
+ }
+}
+
+static GdkFilterReturn
+na_tray_manager_handle_client_message_opcode (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer data)
+{
+ XClientMessageEvent *xevent;
+ NaTrayManager *manager;
+
+ xevent = (XClientMessageEvent *) xev;
+ manager = data;
+
+ switch (xevent->data.l[1])
+ {
+ case SYSTEM_TRAY_REQUEST_DOCK:
+ /* Ignore this one since we don't know on which window this was received
+ * and so we can't know for which screen this is. It will be handled
+ * in na_tray_manager_window_filter() since we also receive it there */
+ break;
+
+ case SYSTEM_TRAY_BEGIN_MESSAGE:
+ na_tray_manager_handle_begin_message (manager, xevent);
+ return GDK_FILTER_REMOVE;
+
+ case SYSTEM_TRAY_CANCEL_MESSAGE:
+ na_tray_manager_handle_cancel_message (manager, xevent);
+ return GDK_FILTER_REMOVE;
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static GdkFilterReturn
+na_tray_manager_window_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = (GdkXEvent *)xev;
+ NaTrayManager *manager = data;
+
+ if (xevent->type == ClientMessage)
+ {
+ /* We handle this client message here. See comment in
+ * na_tray_manager_handle_client_message_opcode() for details */
+ if (xevent->xclient.message_type == manager->opcode_atom &&
+ xevent->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK)
+ {
+ na_tray_manager_handle_dock_request (manager,
+ (XClientMessageEvent *) xevent);
+ return GDK_FILTER_REMOVE;
+ }
+ }
+ else if (xevent->type == SelectionClear)
+ {
+ g_signal_emit (manager, manager_signals[LOST_SELECTION], 0);
+ na_tray_manager_unmanage (manager);
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+#if 0
+//FIXME investigate why this doesn't work
+static gboolean
+na_tray_manager_selection_clear_event (GtkWidget *widget,
+ GdkEventSelection *event,
+ NaTrayManager *manager)
+{
+ g_signal_emit (manager, manager_signals[LOST_SELECTION], 0);
+ na_tray_manager_unmanage (manager);
+
+ return FALSE;
+}
+#endif
+#endif
+
+static void
+na_tray_manager_unmanage (NaTrayManager *manager)
+{
+#ifdef GDK_WINDOWING_X11
+ GdkDisplay *display;
+ guint32 timestamp;
+ GtkWidget *invisible;
+ GdkWindow *window;
+
+ if (manager->invisible == NULL)
+ return;
+
+ invisible = manager->invisible;
+ window = gtk_widget_get_window (invisible);
+
+ g_assert (GTK_IS_INVISIBLE (invisible));
+ g_assert (gtk_widget_get_realized (invisible));
+ g_assert (GDK_IS_WINDOW (window));
+
+ display = gtk_widget_get_display (invisible);
+
+ if (gdk_selection_owner_get_for_display (display, manager->selection_atom) ==
+ window)
+ {
+ timestamp = gdk_x11_get_server_time (window);
+ gdk_selection_owner_set_for_display (display,
+ NULL,
+ manager->selection_atom,
+ timestamp,
+ TRUE);
+ }
+
+ //FIXME: we should also use gdk_remove_client_message_filter when it's
+ //available
+ // See bug #351254
+ gdk_window_remove_filter (window,
+ na_tray_manager_window_filter, manager);
+
+ manager->invisible = NULL; /* prior to destroy for reentrancy paranoia */
+ gtk_widget_destroy (invisible);
+ g_object_unref (G_OBJECT (invisible));
+#endif
+}
+
+static void
+na_tray_manager_set_orientation_property (NaTrayManager *manager)
+{
+#ifdef GDK_WINDOWING_X11
+ GdkWindow *window;
+ GdkDisplay *display;
+ Atom orientation_atom;
+ gulong data[1];
+
+ if (!manager->invisible)
+ return;
+ window = gtk_widget_get_window (manager->invisible);
+ if (!window)
+ return;
+
+ display = gtk_widget_get_display (manager->invisible);
+ orientation_atom = gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_SYSTEM_TRAY_ORIENTATION");
+
+ data[0] = manager->orientation == GTK_ORIENTATION_HORIZONTAL ?
+ SYSTEM_TRAY_ORIENTATION_HORZ :
+ SYSTEM_TRAY_ORIENTATION_VERT;
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (window),
+ orientation_atom,
+ XA_CARDINAL, 32,
+ PropModeReplace,
+ (guchar *) &data, 1);
+#endif
+}
+
+static void
+na_tray_manager_set_visual_property (NaTrayManager *manager)
+{
+#ifdef GDK_WINDOWING_X11
+ GdkWindow *window;
+ GdkDisplay *display;
+ Visual *xvisual;
+ Atom visual_atom;
+ gulong data[1];
+
+ if (!manager->invisible)
+ return;
+ window = gtk_widget_get_window (manager->invisible);
+ if (!window)
+ return;
+
+ /* The visual property is a hint to the tray icons as to what visual they
+ * should use for their windows. If the X server has RGBA colormaps, then
+ * we tell the tray icons to use a RGBA colormap and we'll composite the
+ * icon onto its parents with real transparency. Otherwise, we just tell
+ * the icon to use our colormap, and we'll do some hacks with parent
+ * relative backgrounds to simulate transparency.
+ */
+
+ display = gtk_widget_get_display (manager->invisible);
+ visual_atom = gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_SYSTEM_TRAY_VISUAL");
+
+ if (gdk_screen_get_rgba_visual (manager->screen) != NULL &&
+ gdk_display_supports_composite (display))
+ {
+ xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (manager->screen));
+ }
+ else
+ {
+ /* We actually want the visual of the tray where the icons will
+ * be embedded. In almost all cases, this will be the same as the visual
+ * of the screen.
+ */
+ GdkColormap *colormap;
+
+ colormap = gdk_screen_get_default_colormap (manager->screen);
+ xvisual = GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (colormap));
+ }
+
+ data[0] = XVisualIDFromVisual (xvisual);
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (window),
+ visual_atom,
+ XA_VISUALID, 32,
+ PropModeReplace,
+ (guchar *) &data, 1);
+#endif
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static gboolean
+na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
+ GdkScreen *screen)
+{
+ GdkDisplay *display;
+ Screen *xscreen;
+ GtkWidget *invisible;
+ GdkWindow *window;
+ char *selection_atom_name;
+ guint32 timestamp;
+
+ g_return_val_if_fail (NA_IS_TRAY_MANAGER (manager), FALSE);
+ g_return_val_if_fail (manager->screen == NULL, FALSE);
+
+ /* If there's already a manager running on the screen
+ * we can't create another one.
+ */
+#if 0
+ if (na_tray_manager_check_running_screen_x11 (screen))
+ return FALSE;
+#endif
+
+ manager->screen = screen;
+
+ display = gdk_screen_get_display (screen);
+ xscreen = GDK_SCREEN_XSCREEN (screen);
+
+ invisible = gtk_invisible_new_for_screen (screen);
+ gtk_widget_realize (invisible);
+
+ gtk_widget_add_events (invisible,
+ GDK_PROPERTY_CHANGE_MASK | GDK_STRUCTURE_MASK);
+
+ selection_atom_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d",
+ gdk_screen_get_number (screen));
+ manager->selection_atom = gdk_atom_intern (selection_atom_name, FALSE);
+ g_free (selection_atom_name);
+
+ manager->invisible = invisible;
+ g_object_ref (G_OBJECT (manager->invisible));
+
+ na_tray_manager_set_orientation_property (manager);
+ na_tray_manager_set_visual_property (manager);
+
+ window = gtk_widget_get_window (invisible);
+
+ timestamp = gdk_x11_get_server_time (window);
+
+ /* Check if we could set the selection owner successfully */
+ if (gdk_selection_owner_set_for_display (display,
+ window,
+ manager->selection_atom,
+ timestamp,
+ TRUE))
+ {
+ XClientMessageEvent xev;
+ GdkAtom opcode_atom;
+ GdkAtom message_data_atom;
+
+ xev.type = ClientMessage;
+ xev.window = RootWindowOfScreen (xscreen);
+ xev.message_type = gdk_x11_get_xatom_by_name_for_display (display,
+ "MANAGER");
+
+ xev.format = 32;
+ xev.data.l[0] = timestamp;
+ xev.data.l[1] = gdk_x11_atom_to_xatom_for_display (display,
+ manager->selection_atom);
+ xev.data.l[2] = GDK_WINDOW_XWINDOW (window);
+ xev.data.l[3] = 0; /* manager specific data */
+ xev.data.l[4] = 0; /* manager specific data */
+
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display),
+ RootWindowOfScreen (xscreen),
+ False, StructureNotifyMask, (XEvent *)&xev);
+
+ opcode_atom = gdk_atom_intern ("_NET_SYSTEM_TRAY_OPCODE", FALSE);
+ manager->opcode_atom = gdk_x11_atom_to_xatom_for_display (display,
+ opcode_atom);
+
+ message_data_atom = gdk_atom_intern ("_NET_SYSTEM_TRAY_MESSAGE_DATA",
+ FALSE);
+
+ /* Add a window filter */
+#if 0
+ /* This is for when we lose the selection of _NET_SYSTEM_TRAY_Sx */
+ g_signal_connect (invisible, "selection-clear-event",
+ G_CALLBACK (na_tray_manager_selection_clear_event),
+ manager);
+#endif
+ /* This is for SYSTEM_TRAY_REQUEST_DOCK and SelectionClear */
+ gdk_window_add_filter (window,
+ na_tray_manager_window_filter, manager);
+ /* This is for SYSTEM_TRAY_BEGIN_MESSAGE and SYSTEM_TRAY_CANCEL_MESSAGE */
+ gdk_display_add_client_message_filter (display, opcode_atom,
+ na_tray_manager_handle_client_message_opcode,
+ manager);
+ /* This is for _NET_SYSTEM_TRAY_MESSAGE_DATA */
+ gdk_display_add_client_message_filter (display, message_data_atom,
+ na_tray_manager_handle_client_message_message_data,
+ manager);
+ return TRUE;
+ }
+ else
+ {
+ gtk_widget_destroy (invisible);
+ g_object_unref (invisible);
+ manager->invisible = NULL;
+
+ manager->screen = NULL;
+
+ return FALSE;
+ }
+}
+
+#endif
+
+gboolean
+na_tray_manager_manage_screen (NaTrayManager *manager,
+ GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (manager->screen == NULL, FALSE);
+
+#ifdef GDK_WINDOWING_X11
+ return na_tray_manager_manage_screen_x11 (manager, screen);
+#else
+ return FALSE;
+#endif
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static gboolean
+na_tray_manager_check_running_screen_x11 (GdkScreen *screen)
+{
+ GdkDisplay *display;
+ Atom selection_atom;
+ char *selection_atom_name;
+
+ display = gdk_screen_get_display (screen);
+ selection_atom_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d",
+ gdk_screen_get_number (screen));
+ selection_atom = gdk_x11_get_xatom_by_name_for_display (display,
+ selection_atom_name);
+ g_free (selection_atom_name);
+
+ if (XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display),
+ selection_atom) != None)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#endif
+
+gboolean
+na_tray_manager_check_running (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+#ifdef GDK_WINDOWING_X11
+ return na_tray_manager_check_running_screen_x11 (screen);
+#else
+ return FALSE;
+#endif
+}
+
+void
+na_tray_manager_set_orientation (NaTrayManager *manager,
+ GtkOrientation orientation)
+{
+ g_return_if_fail (NA_IS_TRAY_MANAGER (manager));
+
+ if (manager->orientation != orientation)
+ {
+ manager->orientation = orientation;
+
+ na_tray_manager_set_orientation_property (manager);
+
+ g_object_notify (G_OBJECT (manager), "orientation");
+ }
+}
+
+GtkOrientation
+na_tray_manager_get_orientation (NaTrayManager *manager)
+{
+ g_return_val_if_fail (NA_IS_TRAY_MANAGER (manager), GTK_ORIENTATION_HORIZONTAL);
+
+ return manager->orientation;
+}
diff --git a/applets/notification_area/na-tray-manager.h b/applets/notification_area/na-tray-manager.h
new file mode 100644
index 00000000..be678a28
--- /dev/null
+++ b/applets/notification_area/na-tray-manager.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* na-tray-manager.h
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Used to be: eggtraymanager.h
+ */
+
+#ifndef __NA_TRAY_MANAGER_H__
+#define __NA_TRAY_MANAGER_H__
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#include <gtk/gtk.h>
+
+#include "na-tray-child.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NA_TYPE_TRAY_MANAGER (na_tray_manager_get_type ())
+#define NA_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_TRAY_MANAGER, NaTrayManager))
+#define NA_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_TRAY_MANAGER, NaTrayManagerClass))
+#define NA_IS_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_TRAY_MANAGER))
+#define NA_IS_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_TRAY_MANAGER))
+#define NA_TRAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NA_TYPE_TRAY_MANAGER, NaTrayManagerClass))
+
+typedef struct _NaTrayManager NaTrayManager;
+typedef struct _NaTrayManagerClass NaTrayManagerClass;
+
+struct _NaTrayManager
+{
+ GObject parent_instance;
+
+#ifdef GDK_WINDOWING_X11
+ GdkAtom selection_atom;
+ Atom opcode_atom;
+#endif
+
+ GtkWidget *invisible;
+ GdkScreen *screen;
+ GtkOrientation orientation;
+
+ GList *messages;
+ GHashTable *socket_table;
+};
+
+struct _NaTrayManagerClass
+{
+ GObjectClass parent_class;
+
+ void (* tray_icon_added) (NaTrayManager *manager,
+ NaTrayChild *child);
+ void (* tray_icon_removed) (NaTrayManager *manager,
+ NaTrayChild *child);
+
+ void (* message_sent) (NaTrayManager *manager,
+ NaTrayChild *child,
+ const gchar *message,
+ glong id,
+ glong timeout);
+
+ void (* message_cancelled) (NaTrayManager *manager,
+ NaTrayChild *child,
+ glong id);
+
+ void (* lost_selection) (NaTrayManager *manager);
+};
+
+GType na_tray_manager_get_type (void);
+
+gboolean na_tray_manager_check_running (GdkScreen *screen);
+NaTrayManager *na_tray_manager_new (void);
+gboolean na_tray_manager_manage_screen (NaTrayManager *manager,
+ GdkScreen *screen);
+void na_tray_manager_set_orientation (NaTrayManager *manager,
+ GtkOrientation orientation);
+GtkOrientation na_tray_manager_get_orientation (NaTrayManager *manager);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NA_TRAY_MANAGER_H__ */
diff --git a/applets/notification_area/na-tray.c b/applets/notification_area/na-tray.c
new file mode 100644
index 00000000..b866e880
--- /dev/null
+++ b/applets/notification_area/na-tray.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2003-2006 Vincent Untz
+ * Copyright (C) 2007 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <mate-panel-applet.h>
+#include <mate-panel-applet-mateconf.h>
+
+#include <gtk/gtk.h>
+
+#include "na-tray-manager.h"
+#include "fixedtip.h"
+
+#include "na-tray.h"
+
+#define ICON_SPACING 1
+#define MIN_BOX_SIZE 3
+
+typedef struct
+{
+ NaTrayManager *tray_manager;
+ GSList *all_trays;
+ GHashTable *icon_table;
+ GHashTable *tip_table;
+} TraysScreen;
+
+struct _NaTrayPrivate
+{
+ GdkScreen *screen;
+ TraysScreen *trays_screen;
+
+ GtkWidget *box;
+ GtkWidget *frame;
+
+ guint idle_redraw_id;
+
+ GtkOrientation orientation;
+};
+
+typedef struct
+{
+ char *text;
+ glong id;
+ glong timeout;
+} IconTipBuffer;
+
+typedef struct
+{
+ NaTray *tray; /* tray containing the tray icon */
+ GtkWidget *icon; /* tray icon sending the message */
+ GtkWidget *fixedtip;
+ guint source_id;
+ glong id; /* id of the current message */
+ GSList *buffer; /* buffered messages */
+} IconTip;
+
+enum
+{
+ PROP_0,
+ PROP_ORIENTATION,
+ PROP_SCREEN
+};
+
+static gboolean initialized = FALSE;
+static TraysScreen *trays_screens = NULL;
+
+static void icon_tip_show_next (IconTip *icontip);
+
+/* NaBox, an instantiable GtkBox */
+
+typedef GtkBox NaBox;
+typedef GtkBoxClass NaBoxClass;
+
+static GType na_box_get_type (void);
+
+G_DEFINE_TYPE (NaBox, na_box, GTK_TYPE_BOX)
+
+static void
+na_box_init (NaBox *box)
+{
+}
+
+static void
+na_box_class_init (NaBoxClass *klass)
+{
+}
+
+/* NaTray */
+
+G_DEFINE_TYPE (NaTray, na_tray, GTK_TYPE_BIN)
+
+static NaTray *
+get_tray (TraysScreen *trays_screen)
+{
+ if (trays_screen->all_trays == NULL)
+ return NULL;
+
+ return trays_screen->all_trays->data;
+}
+
+const char *ordered_roles[] = {
+ "keyboard",
+ "volume",
+ "bluetooth",
+ "network",
+ "battery",
+ NULL
+};
+
+const char *wmclass_roles[] = {
+ "Bluetooth-applet", "bluetooth",
+ "Mate-volume-control-applet", "volume",
+ "Nm-applet", "network",
+ "Mate-power-manager", "battery",
+ "keyboard", "keyboard",
+ NULL,
+};
+
+static const char *
+find_role (const char *wmclass)
+{
+ int i;
+
+ for (i = 0; wmclass_roles[i]; i += 2)
+ {
+ if (strcmp (wmclass, wmclass_roles[i]) == 0)
+ return wmclass_roles[i + 1];
+ }
+
+ return NULL;
+}
+
+static int
+find_role_position (const char *role)
+{
+ int i;
+
+ for (i = 0; ordered_roles[i]; i++)
+ {
+ if (strcmp (role, ordered_roles[i]) == 0)
+ break;
+ }
+
+ return i + 1;
+}
+
+static int
+find_icon_position (NaTray *tray,
+ GtkWidget *icon)
+{
+ NaTrayPrivate *priv;
+ int position;
+ char *class_a;
+ const char *role;
+ int role_position;
+ GList *l, *children;
+
+ /* We insert the icons with a known roles in a specific order (the one
+ * defined by ordered_roles), and all other icons at the beginning of the box
+ * (left in LTR). */
+
+ priv = tray->priv;
+ position = 0;
+
+ class_a = NULL;
+ na_tray_child_get_wm_class (NA_TRAY_CHILD (icon), NULL, &class_a);
+ if (!class_a)
+ return position;
+
+ role = find_role (class_a);
+ g_free (class_a);
+ if (!role)
+ return position;
+
+ role_position = find_role_position (role);
+ g_object_set_data (G_OBJECT (icon), "role-position", GINT_TO_POINTER (role_position));
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ for (l = g_list_last (children); l; l = l->prev)
+ {
+ GtkWidget *child = l->data;
+ int rp;
+
+ rp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "role-position"));
+ if (rp == 0 || rp < role_position)
+ {
+ position = g_list_index (children, child) + 1;
+ break;
+ }
+ }
+ g_list_free (children);
+
+ /* should never happen, but it doesn't hurt to be on the safe side */
+ if (position < 0)
+ position = 0;
+
+ return position;
+}
+
+static void
+tray_added (NaTrayManager *manager,
+ GtkWidget *icon,
+ TraysScreen *trays_screen)
+{
+ NaTray *tray;
+ NaTrayPrivate *priv;
+ int position;
+
+ tray = get_tray (trays_screen);
+ if (tray == NULL)
+ return;
+
+ priv = tray->priv;
+
+ g_assert (priv->trays_screen == trays_screen);
+
+ g_hash_table_insert (trays_screen->icon_table, icon, tray);
+
+ position = find_icon_position (tray, icon);
+ gtk_box_pack_start (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (priv->box), icon, position);
+
+ gtk_widget_show (icon);
+}
+
+static void
+tray_removed (NaTrayManager *manager,
+ GtkWidget *icon,
+ TraysScreen *trays_screen)
+{
+ NaTray *tray;
+
+ tray = g_hash_table_lookup (trays_screen->icon_table, icon);
+ if (tray == NULL)
+ return;
+
+ g_assert (tray->priv->trays_screen == trays_screen);
+
+ g_hash_table_remove (trays_screen->icon_table, icon);
+ /* this will also destroy the tip associated to this icon */
+ g_hash_table_remove (trays_screen->tip_table, icon);
+}
+
+static void
+icon_tip_buffer_free (gpointer data,
+ gpointer userdata)
+{
+ IconTipBuffer *buffer;
+
+ buffer = data;
+
+ g_free (buffer->text);
+ buffer->text = NULL;
+
+ g_free (buffer);
+}
+
+static void
+icon_tip_free (gpointer data)
+{
+ IconTip *icontip;
+
+ if (data == NULL)
+ return;
+
+ icontip = data;
+
+ if (icontip->fixedtip != NULL)
+ gtk_widget_destroy (GTK_WIDGET (icontip->fixedtip));
+ icontip->fixedtip = NULL;
+
+ if (icontip->source_id != 0)
+ g_source_remove (icontip->source_id);
+ icontip->source_id = 0;
+
+ if (icontip->buffer != NULL)
+ {
+ g_slist_foreach (icontip->buffer, icon_tip_buffer_free, NULL);
+ g_slist_free (icontip->buffer);
+ }
+ icontip->buffer = NULL;
+
+ g_free (icontip);
+}
+
+static int
+icon_tip_buffer_compare (gconstpointer a,
+ gconstpointer b)
+{
+ const IconTipBuffer *buffer_a = a;
+ const IconTipBuffer *buffer_b = b;
+
+ if (buffer_a == NULL || buffer_b == NULL)
+ return !(buffer_a == buffer_b);
+
+ return buffer_a->id - buffer_b->id;
+}
+
+static void
+icon_tip_show_next_clicked (GtkWidget *widget,
+ gpointer data)
+{
+ icon_tip_show_next ((IconTip *) data);
+}
+
+static gboolean
+icon_tip_show_next_timeout (gpointer data)
+{
+ IconTip *icontip = (IconTip *) data;
+
+ icon_tip_show_next (icontip);
+
+ return FALSE;
+}
+
+static void
+icon_tip_show_next (IconTip *icontip)
+{
+ IconTipBuffer *buffer;
+
+ if (icontip->buffer == NULL)
+ {
+ /* this will also destroy the tip window */
+ g_hash_table_remove (icontip->tray->priv->trays_screen->tip_table,
+ icontip->icon);
+ return;
+ }
+
+ if (icontip->source_id != 0)
+ g_source_remove (icontip->source_id);
+ icontip->source_id = 0;
+
+ buffer = icontip->buffer->data;
+ icontip->buffer = g_slist_remove (icontip->buffer, buffer);
+
+ if (icontip->fixedtip == NULL)
+ {
+ icontip->fixedtip = na_fixed_tip_new (icontip->icon,
+ na_tray_get_orientation (icontip->tray));
+
+ g_signal_connect (icontip->fixedtip, "clicked",
+ G_CALLBACK (icon_tip_show_next_clicked), icontip);
+ }
+
+ na_fixed_tip_set_markup (icontip->fixedtip, buffer->text);
+
+ if (!gtk_widget_get_mapped (icontip->fixedtip))
+ gtk_widget_show (icontip->fixedtip);
+
+ icontip->id = buffer->id;
+
+ if (buffer->timeout > 0)
+ icontip->source_id = g_timeout_add_seconds (buffer->timeout,
+ icon_tip_show_next_timeout,
+ icontip);
+
+ icon_tip_buffer_free (buffer, NULL);
+}
+
+static void
+message_sent (NaTrayManager *manager,
+ GtkWidget *icon,
+ const char *text,
+ glong id,
+ glong timeout,
+ TraysScreen *trays_screen)
+{
+ IconTip *icontip;
+ IconTipBuffer find_buffer;
+ IconTipBuffer *buffer;
+ gboolean show_now;
+
+ icontip = g_hash_table_lookup (trays_screen->tip_table, icon);
+
+ find_buffer.id = id;
+ if (icontip &&
+ (icontip->id == id ||
+ g_slist_find_custom (icontip->buffer, &find_buffer,
+ icon_tip_buffer_compare) != NULL))
+ /* we already have this message, so ignore it */
+ /* FIXME: in an ideal world, we'd remember all the past ids and ignore them
+ * too */
+ return;
+
+ show_now = FALSE;
+
+ if (icontip == NULL)
+ {
+ NaTray *tray;
+
+ tray = g_hash_table_lookup (trays_screen->icon_table, icon);
+ if (tray == NULL)
+ {
+ /* We don't know about the icon sending the message, so ignore it.
+ * But this should never happen since NaTrayManager shouldn't send
+ * us the message if there's no socket for it. */
+ g_critical ("Ignoring a message sent by a tray icon "
+ "we don't know: \"%s\".\n", text);
+ return;
+ }
+
+ icontip = g_new0 (IconTip, 1);
+ icontip->tray = tray;
+ icontip->icon = icon;
+
+ g_hash_table_insert (trays_screen->tip_table, icon, icontip);
+
+ show_now = TRUE;
+ }
+
+ buffer = g_new0 (IconTipBuffer, 1);
+
+ buffer->text = g_strdup (text);
+ buffer->id = id;
+ buffer->timeout = timeout;
+
+ icontip->buffer = g_slist_append (icontip->buffer, buffer);
+
+ if (show_now)
+ icon_tip_show_next (icontip);
+}
+
+static void
+message_cancelled (NaTrayManager *manager,
+ GtkWidget *icon,
+ glong id,
+ TraysScreen *trays_screen)
+{
+ IconTip *icontip;
+ IconTipBuffer find_buffer;
+ GSList *cancel_buffer_l;
+ IconTipBuffer *cancel_buffer;
+
+ icontip = g_hash_table_lookup (trays_screen->tip_table, icon);
+ if (icontip == NULL)
+ return;
+
+ if (icontip->id == id)
+ {
+ icon_tip_show_next (icontip);
+ return;
+ }
+
+ find_buffer.id = id;
+ cancel_buffer_l = g_slist_find_custom (icontip->buffer, &find_buffer,
+ icon_tip_buffer_compare);
+ if (cancel_buffer_l == NULL)
+ return;
+
+ cancel_buffer = cancel_buffer_l->data;
+ icon_tip_buffer_free (cancel_buffer, NULL);
+
+ icontip->buffer = g_slist_remove_link (icontip->buffer, cancel_buffer_l);
+ g_slist_free_1 (cancel_buffer_l);
+}
+
+static void
+update_orientation_for_messages (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ NaTray *tray;
+ IconTip *icontip;
+
+ if (value == NULL)
+ return;
+
+ icontip = value;
+ tray = data;
+ if (icontip->tray != tray)
+ return;
+
+ if (icontip->fixedtip)
+ na_fixed_tip_set_orientation (icontip->fixedtip, tray->priv->orientation);
+}
+
+static void
+update_size_and_orientation (NaTray *tray)
+{
+ NaTrayPrivate *priv = tray->priv;
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->box), priv->orientation);
+
+ /* This only happens when setting the property during object construction */
+ if (!priv->trays_screen)
+ return;
+
+ g_hash_table_foreach (priv->trays_screen->tip_table,
+ update_orientation_for_messages, tray);
+
+ if (get_tray (priv->trays_screen) == tray)
+ na_tray_manager_set_orientation (priv->trays_screen->tray_manager,
+ priv->orientation);
+
+ /* note, you want this larger if the frame has non-NONE relief by default. */
+ switch (priv->orientation)
+ {
+ case GTK_ORIENTATION_VERTICAL:
+ /* Give box a min size so the frame doesn't look dumb */
+ gtk_widget_set_size_request (priv->box, MIN_BOX_SIZE, -1);
+ break;
+ case GTK_ORIENTATION_HORIZONTAL:
+ gtk_widget_set_size_request (priv->box, -1, MIN_BOX_SIZE);
+ break;
+ }
+}
+
+/* Children with alpha channels have been set to be composited by calling
+ * gdk_window_set_composited(). We need to paint these children ourselves.
+ */
+static void
+na_tray_expose_icon (GtkWidget *widget,
+ gpointer data)
+{
+ cairo_t *cr = data;
+
+ if (na_tray_child_has_alpha (NA_TRAY_CHILD (widget)))
+ {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ gdk_cairo_set_source_pixmap (cr,
+ gtk_widget_get_window (widget),
+ allocation.x,
+ allocation.y);
+ cairo_paint (cr);
+ }
+}
+
+static void
+na_tray_expose_box (GtkWidget *box,
+ GdkEventExpose *event)
+{
+ cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (box));
+
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ gtk_container_foreach (GTK_CONTAINER (box), na_tray_expose_icon, cr);
+
+ cairo_destroy (cr);
+}
+
+static void
+na_tray_init (NaTray *tray)
+{
+ NaTrayPrivate *priv;
+
+ priv = tray->priv = G_TYPE_INSTANCE_GET_PRIVATE (tray, NA_TYPE_TRAY, NaTrayPrivate);
+
+ priv->screen = NULL;
+ priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+ priv->frame = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+ gtk_container_add (GTK_CONTAINER (tray), priv->frame);
+ gtk_widget_show (priv->frame);
+
+ priv->box = g_object_new (na_box_get_type (), NULL);
+ g_signal_connect (priv->box, "expose-event",
+ G_CALLBACK (na_tray_expose_box), tray);
+ gtk_box_set_spacing (GTK_BOX (priv->box), ICON_SPACING);
+ gtk_container_add (GTK_CONTAINER (priv->frame), priv->box);
+ gtk_widget_show (priv->box);
+}
+
+static GObject *
+na_tray_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NaTray *tray;
+ NaTrayPrivate *priv;
+ int screen_number;
+
+ object = G_OBJECT_CLASS (na_tray_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_params);
+ tray = NA_TRAY (object);
+ priv = tray->priv;
+
+ g_assert (priv->screen != NULL);
+
+ if (!initialized)
+ {
+ GdkDisplay *display;
+ int n_screens;
+
+ display = gdk_display_get_default ();
+ n_screens = gdk_display_get_n_screens (display);
+ trays_screens = g_new0 (TraysScreen, n_screens);
+ initialized = TRUE;
+ }
+
+ screen_number = gdk_screen_get_number (priv->screen);
+
+ if (trays_screens [screen_number].tray_manager == NULL)
+ {
+ NaTrayManager *tray_manager;
+
+ tray_manager = na_tray_manager_new ();
+
+ if (na_tray_manager_manage_screen (tray_manager, priv->screen))
+ {
+ trays_screens [screen_number].tray_manager = tray_manager;
+
+ g_signal_connect (tray_manager, "tray_icon_added",
+ G_CALLBACK (tray_added),
+ &trays_screens [screen_number]);
+ g_signal_connect (tray_manager, "tray_icon_removed",
+ G_CALLBACK (tray_removed),
+ &trays_screens [screen_number]);
+ g_signal_connect (tray_manager, "message_sent",
+ G_CALLBACK (message_sent),
+ &trays_screens [screen_number]);
+ g_signal_connect (tray_manager, "message_cancelled",
+ G_CALLBACK (message_cancelled),
+ &trays_screens [screen_number]);
+
+ trays_screens [screen_number].icon_table = g_hash_table_new (NULL,
+ NULL);
+ trays_screens [screen_number].tip_table = g_hash_table_new_full (
+ NULL,
+ NULL,
+ NULL,
+ icon_tip_free);
+ }
+ else
+ {
+ g_printerr ("System tray didn't get the system tray manager selection for screen %d\n",
+ screen_number);
+ g_object_unref (tray_manager);
+ }
+ }
+
+ priv->trays_screen = &trays_screens [screen_number];
+ trays_screens [screen_number].all_trays = g_slist_append (trays_screens [screen_number].all_trays,
+ tray);
+
+ update_size_and_orientation (tray);
+
+ return object;
+}
+
+static void
+na_tray_dispose (GObject *object)
+{
+ NaTray *tray = NA_TRAY (object);
+ NaTrayPrivate *priv = tray->priv;
+ TraysScreen *trays_screen = priv->trays_screen;
+
+ if (trays_screen != NULL)
+ {
+ trays_screen->all_trays = g_slist_remove (trays_screen->all_trays, tray);
+
+ if (trays_screen->all_trays == NULL)
+ {
+ /* Make sure we drop the manager selection */
+ g_object_unref (trays_screen->tray_manager);
+ trays_screen->tray_manager = NULL;
+
+ g_hash_table_destroy (trays_screen->icon_table);
+ trays_screen->icon_table = NULL;
+
+ g_hash_table_destroy (trays_screen->tip_table);
+ trays_screen->tip_table = NULL;
+ }
+ else
+ {
+ NaTray *new_tray;
+
+ new_tray = get_tray (trays_screen);
+ if (new_tray != NULL)
+ na_tray_manager_set_orientation (trays_screen->tray_manager,
+ na_tray_get_orientation (new_tray));
+ }
+ }
+
+ priv->trays_screen = NULL;
+
+ if (priv->idle_redraw_id != 0)
+ {
+ g_source_remove (priv->idle_redraw_id);
+ priv->idle_redraw_id = 0;
+ }
+
+ G_OBJECT_CLASS (na_tray_parent_class)->dispose (object);
+}
+
+static void
+na_tray_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ NaTray *tray = NA_TRAY (object);
+ NaTrayPrivate *priv = tray->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ na_tray_set_orientation (tray, g_value_get_enum (value));
+ break;
+ case PROP_SCREEN:
+ priv->screen = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+na_tray_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ gtk_widget_size_request (gtk_bin_get_child (GTK_BIN (widget)), requisition);
+}
+
+static void
+na_tray_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ gtk_widget_size_allocate (gtk_bin_get_child (GTK_BIN (widget)), allocation);
+}
+
+static void
+na_tray_class_init (NaTrayClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->constructor = na_tray_constructor;
+ gobject_class->set_property = na_tray_set_property;
+ gobject_class->dispose = na_tray_dispose;
+
+ widget_class->size_request = na_tray_size_request;
+ widget_class->size_allocate = na_tray_size_allocate;
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_ORIENTATION,
+ g_param_spec_enum ("orientation", "orientation", "orientation",
+ GTK_TYPE_ORIENTATION,
+ GTK_ORIENTATION_HORIZONTAL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_SCREEN,
+ g_param_spec_object ("screen", "screen", "screen",
+ GDK_TYPE_SCREEN,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_type_class_add_private (gobject_class, sizeof (NaTrayPrivate));
+}
+
+NaTray *
+na_tray_new_for_screen (GdkScreen *screen,
+ GtkOrientation orientation)
+{
+ return g_object_new (NA_TYPE_TRAY,
+ "screen", screen,
+ "orientation", orientation,
+ NULL);
+}
+
+void
+na_tray_set_orientation (NaTray *tray,
+ GtkOrientation orientation)
+{
+ NaTrayPrivate *priv = tray->priv;
+
+ if (orientation == priv->orientation)
+ return;
+
+ priv->orientation = orientation;
+
+ update_size_and_orientation (tray);
+}
+
+GtkOrientation
+na_tray_get_orientation (NaTray *tray)
+{
+ return tray->priv->orientation;
+}
+
+static gboolean
+idle_redraw_cb (NaTray *tray)
+{
+ NaTrayPrivate *priv = tray->priv;
+
+ gtk_container_foreach (GTK_CONTAINER (priv->box), (GtkCallback)na_tray_child_force_redraw, tray);
+
+ priv->idle_redraw_id = 0;
+
+ return FALSE;
+}
+
+void
+na_tray_force_redraw (NaTray *tray)
+{
+ NaTrayPrivate *priv = tray->priv;
+
+ /* Force the icons to redraw their backgrounds.
+ */
+ if (priv->idle_redraw_id == 0)
+ priv->idle_redraw_id = g_idle_add ((GSourceFunc) idle_redraw_cb, tray);
+}
diff --git a/applets/notification_area/na-tray.h b/applets/notification_area/na-tray.h
new file mode 100644
index 00000000..1154d378
--- /dev/null
+++ b/applets/notification_area/na-tray.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* na-tray-tray.h
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Used to be: eggtraytray.h
+ */
+
+#ifndef __NA_TRAY_H__
+#define __NA_TRAY_H__
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NA_TYPE_TRAY (na_tray_get_type ())
+#define NA_TRAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_TRAY, NaTray))
+#define NA_TRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_TRAY, NaTrayClass))
+#define NA_IS_TRAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_TRAY))
+#define NA_IS_TRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_TRAY))
+#define NA_TRAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NA_TYPE_TRAY, NaTrayClass))
+
+typedef struct _NaTray NaTray;
+typedef struct _NaTrayPrivate NaTrayPrivate;
+typedef struct _NaTrayClass NaTrayClass;
+
+struct _NaTray
+{
+ GtkBin parent_instance;
+
+ NaTrayPrivate *priv;
+};
+
+struct _NaTrayClass
+{
+ GtkBinClass parent_class;
+};
+
+GType na_tray_get_type (void);
+NaTray *na_tray_new_for_screen (GdkScreen *screen,
+ GtkOrientation orientation);
+void na_tray_set_orientation (NaTray *tray,
+ GtkOrientation orientation);
+GtkOrientation na_tray_get_orientation (NaTray *tray);
+void na_tray_force_redraw (NaTray *tray);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NA_TRAY_H__ */
diff --git a/applets/notification_area/notification-area-menu.xml b/applets/notification_area/notification-area-menu.xml
new file mode 100644
index 00000000..fdbcc83f
--- /dev/null
+++ b/applets/notification_area/notification-area-menu.xml
@@ -0,0 +1,3 @@
+<menuitem name="Notification Area Help Item" action="SystemTrayHelp" />
+<menuitem name="Notification Area About Item" action="SystemTrayAbout" />
+
diff --git a/applets/notification_area/org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in b/applets/notification_area/org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in
new file mode 100644
index 00000000..4c9cc1e0
--- /dev/null
+++ b/applets/notification_area/org.mate.panel.NotificationAreaApplet.mate-panel-applet.in.in
@@ -0,0 +1,17 @@
+[Applet Factory]
+Id=NotificationAreaAppletFactory
+InProcess=@IN_PROCESS@
+Location=@LOCATION@
+_Name=Notification Area Factory
+_Description=Factory for notification area
+
+[NotificationArea]
+_Name=Notification Area
+_Description=Area where notification icons appear
+Icon=mate-panel-notification-area
+MateComponentId=OAFIID:MATE_NotificationAreaApplet;OAFIID:MATE_SystemTrayApplet;
+X-MATE-Bugzilla-Bugzilla=MATE
+X-MATE-Bugzilla-Product=mate-panel
+X-MATE-Bugzilla-Component=notification area
+X-MATE-Bugzilla-Version=@VERSION@
+X-MATE-Bugzilla-OtherBinaries=notification-area-applet
diff --git a/applets/notification_area/org.mate.panel.applet.NotificationAreaAppletFactory.service.in b/applets/notification_area/org.mate.panel.applet.NotificationAreaAppletFactory.service.in
new file mode 100644
index 00000000..cd7d21c0
--- /dev/null
+++ b/applets/notification_area/org.mate.panel.applet.NotificationAreaAppletFactory.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.mate.panel.applet.NotificationAreaAppletFactory
+Exec=@LOCATION@
diff --git a/applets/notification_area/testtray.c b/applets/notification_area/testtray.c
new file mode 100644
index 00000000..d052bedf
--- /dev/null
+++ b/applets/notification_area/testtray.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2002 Anders Carlsson <[email protected]>
+ * Copyright (C) 2003-2006 Vincent Untz
+ * Copyright (C) 2006, 2007 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include "na-tray-manager.h"
+#include "na-tray.h"
+
+#define NOTIFICATION_AREA_ICON "mate-panel-notification-area"
+
+static guint n_windows = 0;
+
+typedef struct
+{
+ GdkScreen *screen;
+ guint screen_num;
+ GtkWidget *window;
+ NaTray *tray;
+ GtkWidget *box;
+ GtkLabel *count_label;
+} TrayData;
+
+static void
+do_add (GtkWidget *child, guint *n_children)
+{
+ *n_children += 1;
+}
+
+static void
+update_child_count (TrayData *data)
+{
+ guint n_children = 0;
+ char text[64];
+
+ if (!gtk_widget_get_realized (data->window))
+ return;
+
+ gtk_container_foreach (GTK_CONTAINER (data->box), (GtkCallback) do_add, &n_children);
+
+ g_snprintf (text, sizeof (text), "%u icons", n_children);
+ gtk_label_set_text (data->count_label, text);
+}
+
+static void
+tray_added_cb (GtkContainer *box, GtkWidget *icon, TrayData *data)
+{
+ g_print ("[Screen %u tray %p] Child %p added to tray: \"%s\"\n",
+ data->screen_num, data->tray, icon, "XXX");//na_tray_child_get_title (icon));
+
+ update_child_count (data);
+}
+
+static void
+tray_removed_cb (GtkContainer *box, GtkWidget *icon, TrayData *data)
+{
+ g_print ("[Screen %u tray %p] Child %p removed from tray\n",
+ data->screen_num, data->tray, icon);
+
+ update_child_count (data);
+}
+
+static void orientation_changed_cb (GtkComboBox *combo, TrayData *data)
+{
+ GtkOrientation orientation = (GtkOrientation) gtk_combo_box_get_active (combo);
+
+ g_print ("[Screen %u tray %p] Setting orientation to \"%s\"\n",
+ data->screen_num, data->tray, orientation == 0 ? "horizontal" : "vertical");
+
+ na_tray_set_orientation (data->tray, orientation);
+}
+
+static void
+maybe_quit (gpointer data,
+ GObject *zombie)
+{
+ if (--n_windows == 0) {
+ gtk_main_quit ();
+ }
+}
+
+static TrayData *create_tray_on_screen (GdkScreen *screen, gboolean force);
+
+static void
+warning_dialog_response_cb (GtkWidget *dialog,
+ gint response,
+ GdkScreen *screen)
+{
+ if (response == GTK_RESPONSE_YES) {
+ create_tray_on_screen (screen, TRUE);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+add_tray_cb (GtkWidget *button, TrayData *data)
+{
+ create_tray_on_screen (data->screen, TRUE);
+}
+
+static TrayData *
+create_tray_on_screen (GdkScreen *screen,
+ gboolean force)
+{
+ GtkWidget *window, *hbox, *vbox, *button, *combo, *label;
+ TrayData *data;
+
+ n_windows++;
+
+ if (!force && na_tray_manager_check_running (screen)) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
+ "Override tray manager?");
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "There is already a tray manager running on screen %d.",
+ gdk_screen_get_number (screen));
+ gtk_window_set_screen (GTK_WINDOW (dialog), screen);
+ g_signal_connect (dialog, "response", G_CALLBACK (warning_dialog_response_cb), screen);
+ gtk_window_present (GTK_WINDOW (dialog));
+ g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) maybe_quit, NULL);
+ return NULL;
+ }
+
+ data = g_new0 (TrayData, 1);
+ data->screen = screen;
+ data->screen_num = gdk_screen_get_number (screen);
+
+ data->window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_object_weak_ref (G_OBJECT (window), (GWeakNotify) maybe_quit, NULL);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ button = gtk_button_new_with_mnemonic ("_Add another tray");
+ g_signal_connect (button, "clicked", G_CALLBACK (add_tray_cb), data);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ label = gtk_label_new_with_mnemonic ("_Orientation:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "Horizontal");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "Vertical");
+ g_signal_connect (combo, "changed",
+ G_CALLBACK (orientation_changed_cb), data);
+ gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+
+ label = gtk_label_new (NULL);
+ data->count_label = GTK_LABEL (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ data->tray = na_tray_new_for_screen (screen, GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (data->tray), TRUE, TRUE, 0);
+
+ data->box = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (data->tray))));
+ g_signal_connect_after (data->box, "add", G_CALLBACK (tray_added_cb), data);
+ g_signal_connect_after (data->box, "remove", G_CALLBACK (tray_removed_cb), data);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+
+ gtk_window_set_screen (GTK_WINDOW (window), screen);
+ gtk_window_set_default_size (GTK_WINDOW (window), -1, 200);
+
+ /* gtk_window_set_resizable (GTK_WINDOW (window), FALSE); */
+
+ gtk_widget_show_all (window);
+
+ update_child_count (data);
+
+ return data;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GdkDisplay *display;
+ GdkScreen *screen;
+ int n_screens, i;
+
+ gtk_init (&argc, &argv);
+
+ gtk_window_set_default_icon_name (NOTIFICATION_AREA_ICON);
+
+ display = gdk_display_get_default ();
+ n_screens = gdk_display_get_n_screens (display);
+ for (i = 0; i < n_screens; ++i) {
+ screen = gdk_display_get_screen (display, i);
+
+ create_tray_on_screen (screen, FALSE);
+ }
+
+ gtk_main ();
+
+ return 0;
+}