[Xfce4-commits] r26037 - in xfce4-panel/trunk: . plugins/systray po
Nick Schermer
nick at xfce.org
Sun Sep 2 13:47:55 CEST 2007
Author: nick
Date: 2007-09-02 11:47:54 +0000 (Sun, 02 Sep 2007)
New Revision: 26037
Added:
xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h
xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
xfce4-panel/trunk/plugins/systray/xfce-tray-marshal.list
xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
Removed:
xfce4-panel/trunk/plugins/systray/systray.c
Modified:
xfce4-panel/trunk/NEWS
xfce4-panel/trunk/plugins/systray/Makefile.am
xfce4-panel/trunk/po/POTFILES.in
xfce4-panel/trunk/po/ar.po
xfce4-panel/trunk/po/az.po
xfce4-panel/trunk/po/be.po
xfce4-panel/trunk/po/bg.po
xfce4-panel/trunk/po/bn_IN.po
xfce4-panel/trunk/po/ca.po
xfce4-panel/trunk/po/cs.po
xfce4-panel/trunk/po/de.po
xfce4-panel/trunk/po/dz.po
xfce4-panel/trunk/po/el.po
xfce4-panel/trunk/po/en_GB.po
xfce4-panel/trunk/po/eo.po
xfce4-panel/trunk/po/es.po
xfce4-panel/trunk/po/es_MX.po
xfce4-panel/trunk/po/et.po
xfce4-panel/trunk/po/eu.po
xfce4-panel/trunk/po/fa.po
xfce4-panel/trunk/po/fi.po
xfce4-panel/trunk/po/fr.po
xfce4-panel/trunk/po/gl.po
xfce4-panel/trunk/po/gu.po
xfce4-panel/trunk/po/he.po
xfce4-panel/trunk/po/hi.po
xfce4-panel/trunk/po/hu.po
xfce4-panel/trunk/po/hy.po
xfce4-panel/trunk/po/it.po
xfce4-panel/trunk/po/ja.po
xfce4-panel/trunk/po/ka.po
xfce4-panel/trunk/po/ko.po
xfce4-panel/trunk/po/lt.po
xfce4-panel/trunk/po/mk.po
xfce4-panel/trunk/po/mr.po
xfce4-panel/trunk/po/ms.po
xfce4-panel/trunk/po/nb_NO.po
xfce4-panel/trunk/po/nl.po
xfce4-panel/trunk/po/pa.po
xfce4-panel/trunk/po/pl.po
xfce4-panel/trunk/po/pt_BR.po
xfce4-panel/trunk/po/pt_PT.po
xfce4-panel/trunk/po/ro.po
xfce4-panel/trunk/po/ru.po
xfce4-panel/trunk/po/sk.po
xfce4-panel/trunk/po/sq.po
xfce4-panel/trunk/po/sv.po
xfce4-panel/trunk/po/ta.po
xfce4-panel/trunk/po/tr.po
xfce4-panel/trunk/po/uk.po
xfce4-panel/trunk/po/vi.po
xfce4-panel/trunk/po/xfce4-panel.pot
xfce4-panel/trunk/po/zh_CN.po
xfce4-panel/trunk/po/zh_TW.po
Log:
* plugins/systray: Rewrite of the system tray plugin. This should
fix the icon size problems (Bugs 3213, 3176, 962, 3478 and 3417),
add option to hide icons in the tray, sort icons by application
name and support multiple lines based on the panel size. The
tray manager code is now integrated in the plugin, so it can be
removed from libxfcegui4.
* NEWS: update
* po/: merge strings
Modified: xfce4-panel/trunk/NEWS
===================================================================
--- xfce4-panel/trunk/NEWS 2007-09-01 21:36:32 UTC (rev 26036)
+++ xfce4-panel/trunk/NEWS 2007-09-02 11:47:54 UTC (rev 26037)
@@ -7,6 +7,11 @@
- Separator can have different styles: space, expanded space, line (default),
handle and old-style dotted handle. Initial patch by Landry Breuil. (Jasper)
- Complete rewrite of the clock plugin. (Nick)
+- Rewrite of the system tray plugin. This should fix the icon size problems
+ (Bugs 3213, 3176, 962, 3478 and 3417), add option to hide icons in the
+ tray, sort icons by application name and support multiple lines based on the
+ panel size. The tray manager code is now integrated in the plugin, so it
+ can be removed from libxfcegui4. (Nick)
- Fix area that is off-limits to other windows (_NET_WM_STRUT hints) for a
Xinerama setup with differently sized monitors (Bug #3097). (Jasper)
- Completely rewritten launcher (Bugs 2336, 2365, 1323, 2262 and 1225)
Modified: xfce4-panel/trunk/plugins/systray/Makefile.am
===================================================================
--- xfce4-panel/trunk/plugins/systray/Makefile.am 2007-09-01 21:36:32 UTC (rev 26036)
+++ xfce4-panel/trunk/plugins/systray/Makefile.am 2007-09-02 11:47:54 UTC (rev 26037)
@@ -11,11 +11,24 @@
plugin_LTLIBRARIES = \
libsystray.la
+
+libsystray_built_sources = \
+ xfce-tray-marshal.c \
+ xfce-tray-marshal.h
libsystray_la_SOURCES = \
- systray.c
+ $(libsystray_built_sources) \
+ xfce-tray-dialogs.c \
+ xfce-tray-dialogs.h \
+ xfce-tray-manager.c \
+ xfce-tray-manager.h \
+ xfce-tray-plugin.c \
+ xfce-tray-plugin.h \
+ xfce-tray-widget.c \
+ xfce-tray-widget.h
libsystray_la_CFLAGS = \
+ $(LIBX11_CFLAGS) \
$(GTK_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(LIBXFCEGUI4_CFLAGS) \
@@ -33,6 +46,7 @@
libsystray_la_LIBADD = \
$(top_builddir)/libxfce4panel/libxfce4panel.la \
+ $(LIBX11_LIBS) \
$(GTK_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
$(LIBXFCEGUI4_LIBS)
@@ -59,10 +73,44 @@
@INTLTOOL_DESKTOP_RULE@
EXTRA_DIST = \
- $(desktop_in_in_files)
+ $(desktop_in_in_files) \
+ xfce-tray-marshal.list
+
+CLEANFILES = \
+ xgen-xtmc \
+ xgen-xtmh
+#
+# Rules to auto-generate built sources
+#
+
+if MAINTAINER_MODE
DISTCLEANFILES = \
$(desktop_DATA) \
- $(desktop_in_files)
+ $(desktop_in_files) \
+ $(libsystray_built_sources) \
+ stamp-xfce-tray-marshal.h
+BUILT_SOURCES = \
+ $(libsystray_built_sources)
+
+xfce-tray-marshal.h: stamp-xfce-tray-marshal.h
+ @true
+stamp-xfce-tray-marshal.h: $(srcdir)/xfce-tray-marshal.list Makefile
+ ( cd $(srcdir) && glib-genmarshal \
+ --prefix="_xfce_tray_marshal" \
+ --header xfce-tray-marshal.list \
+ | sed -e 's/marshal_data);$$/marshal_data) G_GNUC_INTERNAL;/' ) >> xgen-xtmh \
+ && ( cmp -s xgen-xtmh xfce-tray-marshal.h || cp xgen-xtmh xfce-tray-marshal.h ) \
+ && rm -f xgen-xtmh \
+ && echo timestamp > $(@F)
+
+xfce-tray-marshal.c: xfce-tray-marshal.h Makefile
+ ( cd $(srcdir) && glib-genmarshal \
+ --prefix="_xfce_tray_marshal" \
+ --body xfce-tray-marshal.list ) >> xgen-xtmc \
+ && cp xgen-xtmc xfce-tray-marshal.c \
+ && rm -f xgen-xtmc
+endif
+
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
Deleted: xfce4-panel/trunk/plugins/systray/systray.c
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,339 @@
+/* $Id$ */
+/*
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define XFCE_TRAY_DIALOG_ICON_SIZE 16
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/xfce-titled-dialog.h>
+#include <libxfcegui4/xfce-widget-helpers.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-panel-macros.h>
+
+#include "xfce-tray-manager.h"
+#include "xfce-tray-widget.h"
+#include "xfce-tray-plugin.h"
+#include "xfce-tray-dialogs.h"
+
+
+
+enum
+{
+ APPLICATION_ICON,
+ APPLICATION_NAME,
+ APPLICATION_HIDDEN,
+ APPLICATION_DATA,
+ N_COLUMNS
+};
+
+
+
+/* prototypes */
+static gchar *xfce_tray_dialogs_camel_case (const gchar *text);
+static GdkPixbuf *xfce_tray_dialogs_icon (GtkIconTheme *icon_theme,
+ const gchar *name);
+static void xfce_tray_dialogs_show_frame_toggled (GtkToggleButton *button,
+ XfceTrayPlugin *plugin);
+static void xfce_tray_dialogs_treeview_toggled (GtkCellRendererToggle *widget,
+ gchar *path,
+ GtkWidget *treeview);
+static void xfce_tray_dialogs_free_store (GtkListStore *store);
+static void xfce_tray_dialogs_configure_response (GtkWidget *dialog,
+ gint response,
+ XfceTrayPlugin *plugin);
+
+
+
+static gchar *
+xfce_tray_dialogs_camel_case (const gchar *text)
+{
+ const gchar *t;
+ gboolean upper = TRUE;
+ gunichar c;
+ GString *result;
+
+ /* allocate a new string for the result */
+ result = g_string_sized_new (32);
+
+ /* convert the input text */
+ for (t = text; *t != '\0'; t = g_utf8_next_char (t))
+ {
+ /* check the next char */
+ c = g_utf8_get_char (t);
+ if (g_unichar_isspace (c))
+ {
+ upper = TRUE;
+ }
+ else if (upper)
+ {
+ c = g_unichar_toupper (c);
+ upper = FALSE;
+ }
+ else
+ {
+ c = g_unichar_tolower (c);
+ }
+
+ /* append the char to the result */
+ g_string_append_unichar (result, c);
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+
+
+static GdkPixbuf *
+xfce_tray_dialogs_icon (GtkIconTheme *icon_theme,
+ const gchar *name)
+{
+ GdkPixbuf *icon;
+
+ /* try to load the icon from the theme */
+ icon = gtk_icon_theme_load_icon (icon_theme, name, XFCE_TRAY_DIALOG_ICON_SIZE, 0, NULL);
+
+ /* if no icon was found, we could check the childeren it the name is currently in the
+ * tray, if so, create a pixbuf from the window data
+ */
+
+ return icon;
+}
+
+
+
+static void
+xfce_tray_dialogs_show_frame_toggled (GtkToggleButton *button,
+ XfceTrayPlugin *plugin)
+{
+ gboolean active;
+
+ /* get state */
+ active = gtk_toggle_button_get_active (button);
+
+ /* set frame shadow */
+ gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), active ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
+
+ /* save */
+ plugin->show_frame = active;
+}
+
+
+
+static void
+xfce_tray_dialogs_treeview_toggled (GtkCellRendererToggle *widget,
+ gchar *path,
+ GtkWidget *treeview)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ XfceTrayApplication *application;
+ XfceTrayPlugin *plugin;
+
+ /* get the tree model */
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+
+ /* get the tree iter */
+ if (G_LIKELY (gtk_tree_model_get_iter_from_string (model, &iter, path)))
+ {
+ /* get the application data */
+ gtk_tree_model_get (model, &iter, APPLICATION_DATA, &application, -1);
+
+ /* get tray plugin */
+ plugin = g_object_get_data (G_OBJECT (treeview), I_("xfce-tray-plugin"));
+
+ if (G_LIKELY (application && plugin))
+ {
+ /* update the manager */
+ xfce_tray_manager_application_update (plugin->manager, application->name, !application->hidden);
+
+ /* sort and update the tray widget */
+ xfce_tray_widget_sort (XFCE_TRAY_WIDGET (plugin->tray));
+
+ /* set the new list value */
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, APPLICATION_HIDDEN, application->hidden, -1);
+ }
+ }
+}
+
+
+
+static void
+xfce_tray_dialogs_free_store (GtkListStore *store)
+{
+ /* clear store */
+ gtk_list_store_clear (store);
+
+ /* release the store */
+ g_object_unref (G_OBJECT (store));
+}
+
+
+
+static void
+xfce_tray_dialogs_configure_response (GtkWidget *dialog,
+ gint response,
+ XfceTrayPlugin *plugin)
+{
+ /* destroy dialog */
+ gtk_widget_destroy (dialog);
+
+ /* unblock plugin menu */
+ xfce_panel_plugin_unblock_menu (plugin->panel_plugin);
+}
+
+
+
+void
+xfce_tray_dialogs_configure (XfceTrayPlugin *plugin)
+{
+ GtkWidget *dialog, *dialog_vbox;
+ GtkWidget *frame, *bin, *button;
+ GtkWidget *scroll, *treeview;
+ GtkListStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeIter iter;
+ XfceTrayApplication *application;
+ GSList *applications, *li;
+ gchar *name;
+ GtkIconTheme *icon_theme;
+ GdkPixbuf *pixbuf;
+
+ /* lock plugin menu */
+ xfce_panel_plugin_block_menu (plugin->panel_plugin);
+
+ /* create dialog */
+ dialog = xfce_titled_dialog_new_with_buttons (_("System Tray"),
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (GTK_WIDGET (plugin->panel_plugin)));
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-settings");
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (xfce_tray_dialogs_configure_response), plugin);
+
+ dialog_vbox = GTK_DIALOG (dialog)->vbox;
+
+ /* appearance */
+ frame = xfce_create_framebox (_("Appearance"), &bin);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, FALSE, TRUE, 0);
+ //gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_widget_show (frame);
+
+ /* show frame */
+ button = gtk_check_button_new_with_mnemonic (_("Show _frame"));
+ gtk_container_add (GTK_CONTAINER (bin), button);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), plugin->show_frame);
+ g_signal_connect (button, "toggled", G_CALLBACK (xfce_tray_dialogs_show_frame_toggled), plugin);
+ gtk_widget_show (button);
+
+ /* applications */
+ frame = xfce_create_framebox (_("Hidden Applications"), &bin);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, TRUE, TRUE, 0);
+ //gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_widget_show (frame);
+
+ /* scrolled window */
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (bin), scroll);
+ gtk_widget_show (scroll);
+
+ /* create list store */
+ store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
+
+ /* create treeview */
+ treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
+ g_signal_connect_swapped (G_OBJECT (treeview), "destroy", G_CALLBACK (xfce_tray_dialogs_free_store), store);
+ gtk_container_add (GTK_CONTAINER (scroll), treeview);
+ gtk_widget_show (treeview);
+
+ /* connect the plugin to the treeview */
+ g_object_set_data (G_OBJECT (treeview), I_("xfce-tray-plugin"), plugin);
+
+ /* create column */
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_resizable (column, FALSE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+ /* create renders */
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", APPLICATION_ICON, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer, "text", APPLICATION_NAME, NULL);
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer, "active", APPLICATION_HIDDEN, NULL);
+ g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK(xfce_tray_dialogs_treeview_toggled), treeview);
+
+ /* get the icon theme */
+ if (G_LIKELY (gtk_widget_has_screen (dialog)))
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
+ else
+ icon_theme = gtk_icon_theme_get_default ();
+
+ /* get the sorted list of applications */
+ applications = xfce_tray_manager_application_list (plugin->manager, TRUE);
+
+ /* add all the application to the list */
+ for (li = applications; li != NULL; li = li->next)
+ {
+ application = li->data;
+
+ /* create a camel case name of the application */
+ name = xfce_tray_dialogs_camel_case (application->name);
+
+ /* append the application */
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ APPLICATION_NAME, name,
+ APPLICATION_HIDDEN, application->hidden,
+ APPLICATION_DATA, application, -1);
+
+ /* cleanup */
+ g_free (name);
+
+ /* get the application icon */
+ pixbuf = xfce_tray_dialogs_icon (icon_theme, application->name);
+
+ if (pixbuf)
+ {
+ /* set the icon */
+ gtk_list_store_set (store, &iter, APPLICATION_ICON, pixbuf, -1);
+
+ /* release */
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+
+ /* show the dialog */
+ gtk_widget_show (dialog);
+}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,23 @@
+/* $Id$ */
+/*
+ * 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 __XFCE_TRAY_DIALOGS_H__
+#define __XFCE_TRAY_DIALOGS_H__
+
+void xfce_tray_dialogs_configure (XfceTrayPlugin *plugin);
+
+#endif /* !__XFCE_TRAY_DIALOGS_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,1047 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2002 Anders Carlsson <andersca at gnu.org>
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2003-2004 Olivier Fourdan <fourdan at xfce.org>
+ * Copyright (c) 2003-2006 Vincent Untz
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4panel/xfce-panel-macros.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "xfce-tray-manager.h"
+#include "xfce-tray-marshal.h"
+
+
+
+#define XFCE_TRAY_MANAGER_REQUEST_DOCK 0
+#define XFCE_TRAY_MANAGER_BEGIN_MESSAGE 1
+#define XFCE_TRAY_MANAGER_CANCEL_MESSAGE 2
+
+#define XFCE_TRAY_MANAGER_ORIENTATION_HORIZONTAL 0
+#define XFCE_TRAY_MANAGER_ORIENTATION_VERTICAL 1
+
+
+
+/* prototypes */
+static void xfce_tray_manager_class_init (XfceTrayManagerClass *klass);
+static void xfce_tray_manager_init (XfceTrayManager *manager);
+static void xfce_tray_manager_finalize (GObject *object);
+static void xfce_tray_manager_unregister (XfceTrayManager *manager);
+static GdkFilterReturn xfce_tray_manager_window_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer user_data);
+static GdkFilterReturn xfce_tray_manager_handle_client_message_opcode (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
+static GdkFilterReturn xfce_tray_manager_handle_client_message_message_data (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
+static void xfce_tray_manager_handle_begin_message (XfceTrayManager *manager,
+ XClientMessageEvent *xevent);
+static void xfce_tray_manager_handle_cancel_message (XfceTrayManager *manager,
+ XClientMessageEvent *xevent);
+static void xfce_tray_manager_handle_dock_request (XfceTrayManager *manager,
+ XClientMessageEvent *xevent);
+static gboolean xfce_tray_manager_handle_undock_request (GtkSocket *socket,
+ gpointer user_data);
+static gint xfce_tray_manager_application_list_compare (gconstpointer a,
+ gconstpointer b);
+static void xfce_tray_manager_application_free (XfceTrayApplication *application);
+static XfceTrayApplication *xfce_tray_manager_application_find (XfceTrayManager *manager,
+ const gchar *name);
+static void xfce_tray_manager_application_set_socket (XfceTrayManager *manager,
+ GtkWidget *socket,
+ Window xwindow);
+static void xfce_tray_message_free (XfceTrayMessage *message);
+static void xfce_tray_message_remove_from_list (XfceTrayManager *manager,
+ XClientMessageEvent *xevent);
+
+
+enum
+{
+ TRAY_ICON_ADDED,
+ TRAY_ICON_REMOVED,
+ TRAY_MESSAGE_SENT,
+ TRAY_MESSAGE_CANCELLED,
+ TRAY_LOST_SELECTION,
+ LAST_SIGNAL
+};
+
+struct _XfceTrayManagerClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfceTrayManager
+{
+ GObject __parent__;
+
+ /* invisible window */
+ GtkWidget *invisible;
+
+ /* list of client sockets */
+ GHashTable *sockets;
+
+ /* orientation of the tray */
+ GtkOrientation orientation;
+
+ /* list of pending messages */
+ GSList *messages;
+
+ /* _net_system_tray_opcode atom */
+ Atom opcode_atom;
+
+ /* _net_system_tray_s%d atom */
+ GdkAtom selection_atom;
+
+ /* list of known and hidden applications */
+ GSList *applications;
+};
+
+struct _XfceTrayMessage
+{
+ /* message string */
+ gchar *string;
+
+ /* message id */
+ glong id;
+
+ /* x11 window */
+ Window window;
+
+ /* numb3rs */
+ glong length;
+ glong remaining_length;
+ glong timeout;
+};
+
+
+
+static guint xfce_tray_manager_signals[LAST_SIGNAL];
+static GObjectClass *xfce_tray_manager_parent_class;
+
+
+
+GType
+xfce_tray_manager_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (G_TYPE_OBJECT,
+ I_("XfceTrayManager"),
+ sizeof (XfceTrayManagerClass),
+ (GClassInitFunc) xfce_tray_manager_class_init,
+ sizeof (XfceTrayManager),
+ (GInstanceInitFunc) xfce_tray_manager_init,
+ 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+xfce_tray_manager_class_init (XfceTrayManagerClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ /* determine the parent type class */
+ xfce_tray_manager_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = (GObjectClass *)klass;
+ gobject_class->finalize = xfce_tray_manager_finalize;
+
+ xfce_tray_manager_signals[TRAY_ICON_ADDED] =
+ g_signal_new (I_("tray-icon-added"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_SOCKET);
+
+ xfce_tray_manager_signals[TRAY_ICON_REMOVED] =
+ g_signal_new (I_("tray-icon-removed"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_SOCKET);
+
+ xfce_tray_manager_signals[TRAY_MESSAGE_SENT] =
+ g_signal_new (I_("tray-message-sent"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ _xfce_tray_marshal_VOID__OBJECT_STRING_LONG_LONG,
+ G_TYPE_NONE, 4,
+ GTK_TYPE_SOCKET,
+ G_TYPE_STRING,
+ G_TYPE_LONG,
+ G_TYPE_LONG);
+
+ xfce_tray_manager_signals[TRAY_MESSAGE_CANCELLED] =
+ g_signal_new (I_("tray-message-cancelled"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ _xfce_tray_marshal_VOID__OBJECT_LONG,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_SOCKET,
+ G_TYPE_LONG);
+
+ xfce_tray_manager_signals[TRAY_LOST_SELECTION] =
+ g_signal_new (I_("tray-lost-selection"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+
+
+static void
+xfce_tray_manager_init (XfceTrayManager *manager)
+{
+ /* initialize */
+ manager->messages = NULL;
+ manager->invisible = NULL;
+ manager->orientation = GTK_ORIENTATION_HORIZONTAL;
+ manager->applications = NULL;
+
+ /* create new sockets table */
+ manager->sockets = g_hash_table_new (NULL, NULL);
+}
+
+
+
+GQuark
+xfce_tray_manager_error_quark (void)
+{
+ static GQuark q = 0;
+
+ if (q == 0)
+ {
+ q = g_quark_from_static_string ("xfce-tray-manager-error-quark");
+ }
+
+ return q;
+}
+
+
+
+static void
+xfce_tray_manager_finalize (GObject *object)
+{
+ XfceTrayManager *manager = XFCE_TRAY_MANAGER (object);
+
+ /* unregsiter the manager */
+ xfce_tray_manager_unregister (manager);
+
+ /* destroy the hash table */
+ g_hash_table_destroy (manager->sockets);
+
+ if (manager->messages)
+ {
+ /* cleanup all pending messages */
+ g_slist_foreach (manager->messages, (GFunc) xfce_tray_message_free, NULL);
+
+ /* free the list */
+ g_slist_free (manager->messages);
+ }
+
+ if (manager->applications)
+ {
+ /* free all items */
+ g_slist_foreach (manager->applications, (GFunc) xfce_tray_manager_application_free, NULL);
+
+ /* free the list */
+ g_slist_free (manager->applications);
+ }
+
+ G_OBJECT_CLASS (xfce_tray_manager_parent_class)->finalize (object);
+}
+
+
+XfceTrayManager *
+xfce_tray_manager_new (void)
+{
+ return g_object_new (XFCE_TYPE_TRAY_MANAGER, NULL);
+}
+
+
+gboolean
+xfce_tray_manager_check_running (GdkScreen *screen)
+{
+ gchar *selection_name;
+ GdkDisplay *display;
+ Atom selection_atom;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ /* get the display */
+ display = gdk_screen_get_display (screen);
+
+ /* create the selection atom name */
+ selection_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", gdk_screen_get_number (screen));
+
+ /* get the atom */
+ selection_atom = gdk_x11_get_xatom_by_name_for_display (display, selection_name);
+
+ /* cleanup */
+ g_free (selection_name);
+
+ /* return result */
+ return (XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), selection_atom) != None);
+}
+
+
+
+gboolean
+xfce_tray_manager_register (XfceTrayManager *manager,
+ GdkScreen *screen,
+ GError **error)
+{
+ GdkDisplay *display;
+ gchar *selection_name;
+ gboolean succeed;
+ gint screen_number;
+ GtkWidget *invisible;
+ guint32 timestamp;
+ GdkAtom opcode_atom;
+ XClientMessageEvent xevent;
+ Window root_window;
+
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ /* create invisible window */
+ invisible = gtk_invisible_new_for_screen (screen);
+ gtk_widget_realize (invisible);
+
+ /* let the invisible window monitor property and configuration changes */
+ gtk_widget_add_events (invisible, GDK_PROPERTY_CHANGE_MASK | GDK_STRUCTURE_MASK);
+
+ /* get the screen number */
+ screen_number = gdk_screen_get_number (screen);
+
+ /* create the selection atom name */
+ selection_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", screen_number);
+
+ /* get the selection atom */
+ manager->selection_atom = gdk_atom_intern (selection_name, FALSE);
+
+ /* cleanup */
+ g_free (selection_name);
+
+ /* get the display */
+ display = gdk_screen_get_display (screen);
+
+ /* get the current x server time stamp */
+ timestamp = gdk_x11_get_server_time (invisible->window);
+
+ /* try to become the selection owner of this display */
+ succeed = gdk_selection_owner_set_for_display (display, invisible->window, manager->selection_atom, timestamp, TRUE);
+
+ if (G_LIKELY (succeed))
+ {
+ /* get the root window */
+ root_window = RootWindowOfScreen (GDK_SCREEN_XSCREEN (screen));
+
+ /* send a message to x11 that we're going to handle this display */
+ xevent.type = ClientMessage;
+ xevent.window = root_window;
+ xevent.message_type = gdk_x11_get_xatom_by_name_for_display (display, "MANAGER");
+ xevent.format = 32;
+ xevent.data.l[0] = timestamp;
+ xevent.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, manager->selection_atom);
+ xevent.data.l[2] = GDK_WINDOW_XWINDOW (invisible->window);
+ xevent.data.l[3] = 0;
+ xevent.data.l[4] = 0;
+
+ /* send the message */
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display), root_window, False, StructureNotifyMask, (XEvent *)&xevent);
+
+ /* set the invisible window and take a reference */
+ manager->invisible = g_object_ref (G_OBJECT (invisible));
+
+ /* system_tray_request_dock and selectionclear */
+ gdk_window_add_filter (invisible->window, xfce_tray_manager_window_filter, manager);
+
+ /* get the opcode atom (for both gdk and x11) */
+ opcode_atom = gdk_atom_intern ("_NET_SYSTEM_TRAY_OPCODE", FALSE);
+ manager->opcode_atom = gdk_x11_atom_to_xatom_for_display (display, opcode_atom);
+
+ /* system_tray_begin_message and system_tray_cancel_message */
+ gdk_display_add_client_message_filter (display,
+ opcode_atom,
+ xfce_tray_manager_handle_client_message_opcode,
+ manager);
+
+ /* _net_system_tray_message_data */
+ gdk_display_add_client_message_filter (display,
+ gdk_atom_intern ("_NET_SYSTEM_TRAY_MESSAGE_DATA", FALSE),
+ xfce_tray_manager_handle_client_message_message_data,
+ manager);
+ }
+ else
+ {
+ /* desktroy the invisible window */
+ gtk_widget_destroy (invisible);
+
+ /* set an error */
+ g_set_error (error, XFCE_TRAY_MANAGER_ERROR, XFCE_TRAY_MANAGER_ERROR_SELECTION_FAILED,
+ _("Failed to acquire manager selection for screen %d"), screen_number);
+ }
+
+ return succeed;
+}
+
+
+
+static void
+xfce_tray_manager_unregister (XfceTrayManager *manager)
+{
+ GdkDisplay *display;
+ GtkWidget *invisible = manager->invisible;
+
+ /* leave when there is no invisible window */
+ if (G_UNLIKELY (invisible == NULL))
+ return;
+
+ g_return_if_fail (GTK_IS_INVISIBLE (invisible));
+ g_return_if_fail (GTK_WIDGET_REALIZED (invisible));
+ g_return_if_fail (GDK_IS_WINDOW (invisible->window));
+
+ /* get the display of the invisible window */
+ display = gtk_widget_get_display (invisible);
+
+ /* remove our handling of the selection if we're the owner */
+ if (gdk_selection_owner_get_for_display (display, manager->selection_atom) == invisible->window)
+ {
+ /* reset the selection owner */
+ gdk_selection_owner_set_for_display (display,
+ NULL,
+ manager->selection_atom,
+ gdk_x11_get_server_time (invisible->window),
+ TRUE);
+ }
+
+ /* remove window filter */
+ gdk_window_remove_filter (invisible->window, xfce_tray_manager_window_filter, manager);
+
+ /* destroy and unref the invisible window */
+ manager->invisible = NULL;
+ gtk_widget_destroy (invisible);
+ g_object_unref (G_OBJECT (invisible));
+}
+
+
+
+static GdkFilterReturn
+xfce_tray_manager_window_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XEvent *xevent = (XEvent *)xev;
+ XfceTrayManager *manager = XFCE_TRAY_MANAGER (user_data);
+
+ if (xevent->type == ClientMessage)
+ {
+ if (xevent->xclient.message_type == manager->opcode_atom
+ && xevent->xclient.data.l[1] == XFCE_TRAY_MANAGER_REQUEST_DOCK)
+ {
+ /* dock a tray icon */
+ xfce_tray_manager_handle_dock_request (manager, (XClientMessageEvent *) xevent);
+
+ return GDK_FILTER_REMOVE;
+ }
+ }
+ else if (xevent->type == SelectionClear)
+ {
+ /* emit the signal */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_LOST_SELECTION], 0);
+
+ /* unregister the manager */
+ xfce_tray_manager_unregister (manager);
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+
+static GdkFilterReturn
+xfce_tray_manager_handle_client_message_opcode (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XClientMessageEvent *xev;
+ XfceTrayManager *manager = XFCE_TRAY_MANAGER (user_data);
+
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), GDK_FILTER_REMOVE);
+
+ /* cast to x11 event */
+ xev = (XClientMessageEvent *) xevent;
+
+ switch (xev->data.l[1])
+ {
+ case XFCE_TRAY_MANAGER_REQUEST_DOCK:
+ /* handled in xfce_tray_manager_window_filter () */
+ break;
+
+ case XFCE_TRAY_MANAGER_BEGIN_MESSAGE:
+ xfce_tray_manager_handle_begin_message (manager, xev);
+ return GDK_FILTER_REMOVE;
+
+ case XFCE_TRAY_MANAGER_CANCEL_MESSAGE:
+ xfce_tray_manager_handle_cancel_message (manager, xev);
+ return GDK_FILTER_REMOVE;
+
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+
+static GdkFilterReturn
+xfce_tray_manager_handle_client_message_message_data (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XClientMessageEvent *xev;
+ XfceTrayManager *manager = XFCE_TRAY_MANAGER (user_data);
+ GSList *li;
+ XfceTrayMessage *message;
+ glong length;
+ GtkSocket *socket;
+
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), GDK_FILTER_REMOVE);
+
+ /* try to find the pending message in the list */
+ for (li = manager->messages; li != NULL; li = li->next)
+ {
+ message = li->data;
+
+ if (xev->window == message->window)
+ {
+ /* copy the data of this message */
+ length = MIN (message->remaining_length, 20);
+ memcpy ((message->string + message->length - message->remaining_length), &xev->data, length);
+ message->remaining_length -= length;
+
+ /* check if we have the complete message */
+ if (message->remaining_length == 0)
+ {
+ /* try to get the socket from the known tray icons */
+ socket = g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (message->window));
+
+ if (G_LIKELY (socket))
+ {
+ /* known socket, send the signal */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_MESSAGE_SENT], 0,
+ socket, message->string, message->id, message->timeout);
+ }
+
+ /* delete the message from the list */
+ manager->messages = g_slist_delete_link (manager->messages, li);
+
+ /* free the message */
+ xfce_tray_message_free (message);
+ }
+
+ /* stop searching */
+ break;
+ }
+ }
+
+ return GDK_FILTER_REMOVE;
+}
+
+
+
+static void
+xfce_tray_manager_handle_begin_message (XfceTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkSocket *socket;
+ XfceTrayMessage *message;
+ glong length, timeout, id;
+
+ /* try to find the window in the list of known tray icons */
+ socket = g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (xevent->window));
+
+ /* unkown tray icon: ignore the message */
+ if (G_UNLIKELY (socket == NULL))
+ return;
+
+ /* remove the same message from the list */
+ xfce_tray_message_remove_from_list (manager, xevent);
+
+ /* get some message information */
+ timeout = xevent->data.l[2];
+ length = xevent->data.l[3];
+ id = xevent->data.l[4];
+
+ if (length == 0)
+ {
+ /* directly emit empty messages */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_MESSAGE_SENT], 0,
+ socket, "", id, timeout);
+ }
+ else
+ {
+ /* create new structure */
+ message = panel_slice_new0 (XfceTrayMessage);
+
+ /* set message data */
+ message->window = xevent->window;
+ message->timeout = timeout;
+ message->length = length;
+ message->id = id;
+ message->remaining_length = length;
+ message->string = g_malloc (length + 1);
+ message->string[length] = '\0';
+
+ /* add this message to the list of pending messages */
+ manager->messages = g_slist_prepend (manager->messages, message);
+ }
+}
+
+
+
+static void
+xfce_tray_manager_handle_cancel_message (XfceTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkSocket *socket;
+
+ /* remove the same message from the list */
+ xfce_tray_message_remove_from_list (manager, xevent);
+
+ /* try to find the window in the list of known tray icons */
+ socket = g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (xevent->window));
+
+ if (G_LIKELY (socket))
+ {
+ /* emit the cancelled signal */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_MESSAGE_CANCELLED], 0,
+ socket, xevent->data.l[2]);
+ }
+}
+
+
+
+static void
+xfce_tray_manager_handle_dock_request (XfceTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkWidget *socket;
+ Window *xwindow;
+
+ /* check if we already have this notification */
+ if (g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (xevent->data.l[2])))
+ return;
+
+ /* create a new socket */
+ socket = gtk_socket_new ();
+
+ /* allow applications to draw on this widget */
+ gtk_widget_set_app_paintable (socket, TRUE);
+
+ /* allocate and set the xwindow */
+ xwindow = g_new (Window, 1);
+ *xwindow = xevent->data.l[2];
+
+ /* connect the xwindow data to the socket */
+ g_object_set_data_full (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"), xwindow, g_free);
+
+ /* set the application on the socket */
+ xfce_tray_manager_application_set_socket (manager, socket, *xwindow);
+
+ /* emit signal */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_ADDED], 0, socket);
+
+ /* check if the widget has been attached. if it has not been attached,
+ * there's no need to add the socket to the hash table. */
+ if (G_LIKELY (GTK_IS_WINDOW (gtk_widget_get_toplevel (socket))))
+ {
+ /* signal to monitor if the client is removed from the socket */
+ g_signal_connect (G_OBJECT (socket), "plug-removed", G_CALLBACK (xfce_tray_manager_handle_undock_request), manager);
+
+ /* register the xembed client window id for this socket */
+ gtk_socket_add_id (GTK_SOCKET (socket), *xwindow);
+
+ /* add the socket to the list of known sockets */
+ g_hash_table_insert (manager->sockets, GUINT_TO_POINTER (*xwindow), socket);
+ }
+ else
+ {
+ /* not attached successfully, destroy it */
+ gtk_widget_destroy (socket);
+ }
+}
+
+
+
+static gboolean
+xfce_tray_manager_handle_undock_request (GtkSocket *socket,
+ gpointer user_data)
+{
+ XfceTrayManager *manager = XFCE_TRAY_MANAGER (user_data);
+ Window *xwindow;
+
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), FALSE);
+
+ /* emit signal that the socket will be removed */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_REMOVED], 0, socket);
+
+ /* get the xwindow */
+ xwindow = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"));
+
+ /* remove the socket from the list */
+ g_hash_table_remove (manager->sockets, GUINT_TO_POINTER (*xwindow));
+
+ /* unset object data */
+ g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"), NULL);
+ g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-application"), NULL);
+
+ /* destroy the socket */
+ return FALSE;
+}
+
+
+
+GtkOrientation
+xfce_tray_manager_get_orientation (XfceTrayManager *manager)
+{
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), GTK_ORIENTATION_HORIZONTAL);
+
+ return manager->orientation;
+}
+
+
+
+void
+xfce_tray_manager_set_orientation (XfceTrayManager *manager,
+ GtkOrientation orientation)
+{
+ GdkDisplay *display;
+ Atom orientation_atom;
+ gulong data[1];
+
+ g_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
+ g_return_if_fail (GTK_IS_INVISIBLE (manager->invisible));
+
+ if (G_LIKELY (manager->orientation != orientation))
+ {
+ /* set the new orientation */
+ manager->orientation = orientation;
+
+ /* get invisible display */
+ display = gtk_widget_get_display (manager->invisible);
+
+ /* get the xatom for the orientation property */
+ orientation_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_XFCE_TRAY_MANAGER_ORIENTATION");
+
+ /* set the data we're going to send to x */
+ data[0] = (manager->orientation == GTK_ORIENTATION_HORIZONTAL ?
+ XFCE_TRAY_MANAGER_ORIENTATION_HORIZONTAL : XFCE_TRAY_MANAGER_ORIENTATION_VERTICAL);
+
+ /* change the x property */
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (manager->invisible->window),
+ orientation_atom,
+ XA_CARDINAL, 32,
+ PropModeReplace,
+ (guchar *) &data, 1);
+ }
+}
+
+
+
+/**
+ * known tray applications
+ **/
+XfceTrayApplication *
+xfce_tray_manager_application_add (XfceTrayManager *manager,
+ const gchar *name,
+ gboolean hidden)
+{
+ XfceTrayApplication *application;
+
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), NULL);
+ g_return_val_if_fail (name, NULL);
+
+ /* create structure */
+ application = panel_slice_new0 (XfceTrayApplication);
+
+ /* set values */
+ application->name = g_strdup (name);
+ application->hidden = hidden;
+
+ /* add to the list */
+ manager->applications = g_slist_prepend (manager->applications, application);
+
+ /* return the pointer */
+ return application;
+}
+
+
+
+void
+xfce_tray_manager_application_update (XfceTrayManager *manager,
+ const gchar *name,
+ gboolean hidden)
+{
+ GSList *li;
+ XfceTrayApplication *application;
+
+ g_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
+ g_return_if_fail (name);
+
+ /* walk through the known window names */
+ for (li = manager->applications; li != NULL; li = li->next)
+ {
+ application = li->data;
+
+ /* check if the names match */
+ if (strcmp (application->name, name) == 0)
+ {
+ /* set the new hidden state */
+ application->hidden = hidden;
+
+ /* stop searching */
+ break;
+ }
+ }
+}
+
+
+
+static gint
+xfce_tray_manager_application_list_compare (gconstpointer a,
+ gconstpointer b)
+{
+ XfceTrayApplication *app_a = (XfceTrayApplication *)a;
+ XfceTrayApplication *app_b = (XfceTrayApplication *)b;
+
+ /* sort order when one of the names is null */
+ if (G_UNLIKELY (app_a->name == NULL || app_b->name == NULL))
+ return (app_a->name == app_b->name ? 0 : (app_a->name == NULL ? -1 : 1));
+
+ return strcmp (app_a->name, app_b->name);
+}
+
+
+
+GSList *
+xfce_tray_manager_application_list (XfceTrayManager *manager,
+ gboolean sorted)
+{
+ g_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), NULL);
+
+ /* sort the list if requested */
+ if (sorted)
+ manager->applications = g_slist_sort (manager->applications, xfce_tray_manager_application_list_compare);
+
+ /* return the list */
+ return manager->applications;
+}
+
+
+
+static void
+xfce_tray_manager_application_free (XfceTrayApplication *application)
+{
+ /* free name */
+ g_free (application->name);
+
+ /* free structure */
+ panel_slice_free (XfceTrayApplication, application);
+}
+
+
+
+static XfceTrayApplication *
+xfce_tray_manager_application_find (XfceTrayManager *manager,
+ const gchar *name)
+{
+ GSList *li;
+ XfceTrayApplication *application;
+
+ g_return_val_if_fail (name, NULL);
+
+ /* walk through the known window names */
+ for (li = manager->applications; li != NULL; li = li->next)
+ {
+ application = li->data;
+
+ /* find a matching name and return the pointer */
+ if (strcmp (application->name, name) == 0)
+ return application;
+ }
+
+ /* no match was found, add the application and return the pointer */
+ return xfce_tray_manager_application_add (manager, name, FALSE);
+}
+
+
+
+static void
+xfce_tray_manager_application_set_socket (XfceTrayManager *manager,
+ GtkWidget *socket,
+ Window xwindow)
+{
+ gchar *name;
+ GdkDisplay *display;
+ gint succeed;
+ XTextProperty xprop;
+ XfceTrayApplication *application;
+
+ /* get the display of the socket */
+ display = gtk_widget_get_display (socket);
+
+ /* avoid exiting the application on X errors */
+ gdk_error_trap_push ();
+
+ /* try to get the wm name (this is more relaiable with qt applications) */
+ succeed = XGetWMName (GDK_DISPLAY_XDISPLAY (display), xwindow, &xprop);
+
+ /* check if everything went fine */
+ if (G_LIKELY (gdk_error_trap_pop () == 0 && succeed >= Success))
+ {
+ /* check the xprop content */
+ if (G_LIKELY (xprop.value && xprop.nitems > 0))
+ {
+ /* if the string is utf-8 valid, set the name */
+ if (G_LIKELY (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL)))
+ {
+ /* create the application name (lower case) */
+ name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
+
+ /* find or create a structure */
+ application = xfce_tray_manager_application_find (manager, name);
+
+ /* cleanup */
+ g_free (name);
+
+ /* set the object data */
+ g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-application"), application);
+ }
+
+ /* cleanup */
+ XFree (xprop.value);
+ }
+ }
+}
+
+
+
+const gchar *
+xfce_tray_manager_application_get_name (GtkWidget *socket)
+{
+ XfceTrayApplication *application;
+
+ /* get the application data */
+ application = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-application"));
+
+ return (application ? application->name : NULL);
+}
+
+
+
+gboolean
+xfce_tray_manager_application_get_hidden (GtkWidget *socket)
+{
+ XfceTrayApplication *application;
+
+ /* get the application data */
+ application = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-application"));
+
+ return (application ? application->hidden : FALSE);
+}
+
+
+
+/**
+ * tray messages
+ **/
+static void
+xfce_tray_message_free (XfceTrayMessage *message)
+{
+ /* cleanup */
+ g_free (message->string);
+
+ /* remove slice */
+ panel_slice_free (XfceTrayMessage, message);
+}
+
+
+
+static void
+xfce_tray_message_remove_from_list (XfceTrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GSList *li;
+ XfceTrayMessage *message;
+
+ /* seach for the same message in the list of pending messages */
+ for (li = manager->messages; li != NULL; li = li->next)
+ {
+ message = li->data;
+
+ /* check if this is the same message */
+ if (xevent->window == message->window && xevent->data.l[4] == message->id)
+ {
+ /* delete the message from the list */
+ manager->messages = g_slist_delete_link (manager->messages, li);
+
+ /* free the message */
+ xfce_tray_message_free (message);
+
+ break;
+ }
+ }
+}
+
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,87 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2002 Anders Carlsson <andersca at gnu.org>
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2003-2004 Olivier Fourdan <fourdan at xfce.org>
+ * Copyright (c) 2003-2006 Vincent Untz
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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 __XFCE_TRAY_MANAGER_H__
+#define __XFCE_TRAY_MANAGER_H__
+
+typedef struct _XfceTrayManagerClass XfceTrayManagerClass;
+typedef struct _XfceTrayManager XfceTrayManager;
+typedef struct _XfceTrayMessage XfceTrayMessage;
+typedef struct _XfceTrayApplication XfceTrayApplication;
+
+struct _XfceTrayApplication
+{
+ /* the name of the applications */
+ gchar *name;
+
+ /* whether it should be hidden */
+ guint hidden : 1;
+};
+
+enum
+{
+ XFCE_TRAY_MANAGER_ERROR_SELECTION_FAILED
+};
+
+#define XFCE_TYPE_TRAY_MANAGER (xfce_tray_manager_get_type ())
+#define XFCE_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_TRAY_MANAGER, XfceTrayManager))
+#define XFCE_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_TRAY_MANAGER, XfceTrayManagerClass))
+#define XFCE_IS_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_TRAY_MANAGER))
+#define XFCE_IS_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_TRAY_MANAGER))
+#define XFCE_TRAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_TRAY_MANAGER, XfceTrayManagerClass))
+#define XFCE_TRAY_MANAGER_ERROR (xfce_tray_manager_error_quark())
+
+GType xfce_tray_manager_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+GQuark xfce_tray_manager_error_quark (void) G_GNUC_INTERNAL;
+
+XfceTrayManager *xfce_tray_manager_new (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+gboolean xfce_tray_manager_check_running (GdkScreen *screen) G_GNUC_INTERNAL;
+
+gboolean xfce_tray_manager_register (XfceTrayManager *manager,
+ GdkScreen *screen,
+ GError **error) G_GNUC_INTERNAL;
+
+GtkOrientation xfce_tray_manager_get_orientation (XfceTrayManager *manager) G_GNUC_INTERNAL;
+
+void xfce_tray_manager_set_orientation (XfceTrayManager *manager,
+ GtkOrientation orientation) G_GNUC_INTERNAL;
+
+XfceTrayApplication *xfce_tray_manager_application_add (XfceTrayManager *manager,
+ const gchar *name,
+ gboolean hidden) G_GNUC_INTERNAL;
+
+void xfce_tray_manager_application_update (XfceTrayManager *manager,
+ const gchar *name,
+ gboolean hidden) G_GNUC_INTERNAL;
+
+GSList *xfce_tray_manager_application_list (XfceTrayManager *manager,
+ gboolean sorted) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+const gchar *xfce_tray_manager_application_get_name (GtkWidget *socket) G_GNUC_INTERNAL;
+
+gboolean xfce_tray_manager_application_get_hidden (GtkWidget *socket) G_GNUC_INTERNAL;
+
+
+#endif /* !__XFCE_TRAY_MANAGER_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-marshal.list
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-marshal.list (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-marshal.list 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,2 @@
+VOID:OBJECT,STRING,LONG,LONG
+VOID:OBJECT,LONG
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-marshal.list
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,421 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define XFCE_TRAY_PLUGIN_LINE_HEIGHT (24 + 2)
+
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-panel-macros.h>
+
+#include "xfce-tray-manager.h"
+#include "xfce-tray-widget.h"
+#include "xfce-tray-plugin.h"
+#include "xfce-tray-dialogs.h"
+
+
+
+/* prototypes */
+static void xfce_tray_plugin_message (GtkMessageType type,
+ GdkScreen *screen,
+ const gchar *message);
+static gboolean xfce_tray_plugin_check (GdkScreen *screen);
+static GtkArrowType xfce_tray_plugin_button_position (XfcePanelPlugin *panel_plugin);
+static XfceTrayPlugin *xfce_tray_plugin_new (XfcePanelPlugin *panel_plugin);
+static void xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
+ XfceScreenPosition position);
+static void xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
+ GtkOrientation orientation);
+static gboolean xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
+ guint size);
+static void xfce_tray_plugin_read (XfceTrayPlugin *plugin);
+static void xfce_tray_plugin_write (XfceTrayPlugin *plugin);
+static void xfce_tray_plugin_free (XfceTrayPlugin *plugin);
+static void xfce_tray_plugin_construct (XfcePanelPlugin *panel_plugin);
+
+
+
+/* register the plugin */
+XFCE_PANEL_PLUGIN_REGISTER_INTERNAL_WITH_CHECK (xfce_tray_plugin_construct, xfce_tray_plugin_check);
+
+
+
+static void
+xfce_tray_plugin_message (GtkMessageType type,
+ GdkScreen *screen,
+ const gchar *message)
+{
+ GtkWidget *dialog;
+
+ /* create a dialog */
+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_CLOSE, _("System Tray"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", message);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_screen (GTK_WINDOW (dialog), screen);
+
+ /* run the dialog */
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ /* destroy */
+ gtk_widget_destroy (dialog);
+}
+
+
+
+static gboolean
+xfce_tray_plugin_check (GdkScreen *screen)
+{
+ gboolean running;
+
+
+ /* check if there is already a tray running */
+ running = xfce_tray_manager_check_running (screen);
+
+ /* message */
+ if (running)
+ xfce_tray_plugin_message (GTK_MESSAGE_INFO, screen,
+ _("There is already a system tray running on this screen"));
+
+ return (!running);
+}
+
+
+
+static GtkArrowType
+xfce_tray_plugin_button_position (XfcePanelPlugin *panel_plugin)
+{
+ XfceScreenPosition position;
+ GdkScreen *screen;
+ GdkRectangle geom;
+ gint mon, x, y;
+
+ g_return_val_if_fail (GTK_WIDGET_REALIZED (panel_plugin), GTK_ARROW_LEFT);
+
+ /* get the plugin position */
+ position = xfce_panel_plugin_get_screen_position (panel_plugin);
+
+ /* get the button position */
+ switch (position)
+ {
+ /* horizontal west */
+ case XFCE_SCREEN_POSITION_NW_H:
+ case XFCE_SCREEN_POSITION_SW_H:
+ return GTK_ARROW_RIGHT;
+
+ /* horizontal east */
+ case XFCE_SCREEN_POSITION_N:
+ case XFCE_SCREEN_POSITION_NE_H:
+ case XFCE_SCREEN_POSITION_S:
+ case XFCE_SCREEN_POSITION_SE_H:
+ return GTK_ARROW_LEFT;
+
+ /* vertical north */
+ case XFCE_SCREEN_POSITION_NW_V:
+ case XFCE_SCREEN_POSITION_NE_V:
+ return GTK_ARROW_DOWN;
+
+ /* vertical south */
+ case XFCE_SCREEN_POSITION_W:
+ case XFCE_SCREEN_POSITION_SW_V:
+ case XFCE_SCREEN_POSITION_E:
+ case XFCE_SCREEN_POSITION_SE_V:
+ return GTK_ARROW_UP;
+
+ /* floating */
+ default:
+ /* get the screen information */
+ screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
+ mon = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (panel_plugin)->window);
+ gdk_screen_get_monitor_geometry (screen, mon, &geom);
+ gdk_window_get_root_origin (GTK_WIDGET (panel_plugin)->window, &x, &y);
+
+ /* get the position based on the screen position */
+ if (position == XFCE_SCREEN_POSITION_FLOATING_H)
+ return ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
+ else
+ return ((y < (geom.y + geom.height / 2)) ? GTK_ARROW_DOWN : GTK_ARROW_UP);
+ }
+}
+
+
+
+static XfceTrayPlugin *
+xfce_tray_plugin_new (XfcePanelPlugin *panel_plugin)
+{
+ XfceTrayPlugin *plugin;
+ GError *error = NULL;
+ GtkArrowType position;
+ GdkScreen *screen;
+
+ /* create structure */
+ plugin = panel_slice_new0 (XfceTrayPlugin);
+
+ /* set some data */
+ plugin->panel_plugin = panel_plugin;
+ plugin->manager = NULL;
+ plugin->show_frame = TRUE;
+
+ /* get the button position */
+ position = xfce_tray_plugin_button_position (panel_plugin);
+
+ /* get the screen of the plugin */
+ screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
+
+ /* try to create the tray */
+ plugin->tray = xfce_tray_widget_new_for_screen (screen, position, &error);
+
+ if (G_LIKELY (plugin->tray))
+ {
+ /* get the manager */
+ plugin->manager = xfce_tray_widget_get_manager (XFCE_TRAY_WIDGET (plugin->tray));
+
+ /* read the plugin settings */
+ xfce_tray_plugin_read (plugin);
+
+ /* create the frame */
+ plugin->frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), plugin->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->frame);
+ gtk_widget_show (plugin->frame);
+
+ /* add the tray */
+ gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->tray);
+ gtk_widget_show (plugin->tray);
+ }
+ else
+ {
+ /* show the message */
+ xfce_tray_plugin_message (GTK_MESSAGE_ERROR, screen, error->message);
+
+ /* cleanup */
+ g_error_free (error);
+ }
+
+ return plugin;
+}
+
+
+
+static void
+xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
+ XfceScreenPosition position)
+{
+ GtkArrowType button_position;
+
+ /* get the new position */
+ button_position = xfce_tray_plugin_button_position (plugin->panel_plugin);
+
+ /* set the position */
+ xfce_tray_widget_set_arrow_position (XFCE_TRAY_WIDGET (plugin->tray), button_position);
+
+ /* set the size again */
+ xfce_tray_plugin_size_changed (plugin, xfce_panel_plugin_get_size (plugin->panel_plugin));
+}
+
+
+
+static void
+xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
+ GtkOrientation orientation)
+{
+ /* invoke the function above */
+ xfce_tray_plugin_screen_position_changed (plugin, XFCE_SCREEN_POSITION_NONE);
+}
+
+
+
+static gboolean
+xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
+ guint size)
+{
+ /* set the frame border size */
+ gtk_container_set_border_width (GTK_CONTAINER (plugin->frame), size > 26 ? 1 : 0);
+
+ /* extract the frame from the size for the tray */
+ size -= size > 26 ? 6 : 4;
+
+ /* set the number of lines */
+ xfce_tray_widget_set_lines (XFCE_TRAY_WIDGET (plugin->tray), MAX (1, size / XFCE_TRAY_PLUGIN_LINE_HEIGHT));
+
+ /* set the size */
+ if (xfce_panel_plugin_get_orientation (plugin->panel_plugin) == GTK_ORIENTATION_HORIZONTAL)
+ gtk_widget_set_size_request (plugin->tray, -1, size);
+ else
+ gtk_widget_set_size_request (plugin->tray, size, -1);
+
+ /* we handled the size of the plugin */
+ return TRUE;
+}
+
+
+
+static void
+xfce_tray_plugin_read (XfceTrayPlugin *plugin)
+{
+ gchar *file;
+ gchar **applications;
+ gboolean hidden;
+ XfceRc *rc;
+ guint i;
+
+ /* get rc file name */
+ file = xfce_panel_plugin_lookup_rc_file (plugin->panel_plugin);
+
+ if (G_LIKELY (file))
+ {
+ /* open the file, readonly */
+ rc = xfce_rc_simple_open (file, TRUE);
+
+ /* cleanup */
+ g_free (file);
+
+ if (G_LIKELY (rc))
+ {
+ /* save global plugin settings */
+ xfce_rc_set_group (rc, "Global");
+
+ /* frame setting */
+ plugin->show_frame = xfce_rc_read_bool_entry (rc, "ShowFrame", TRUE);
+
+ if (G_LIKELY (plugin->manager))
+ {
+ /* list of known applications */
+ applications = xfce_rc_get_entries (rc, "Applications");
+
+ if (G_LIKELY (applications))
+ {
+ /* set the group */
+ xfce_rc_set_group (rc, "Applications");
+
+ /* read their visibility */
+ for (i = 0; applications[i] != NULL; i++)
+ {
+ /* whether the application is hidden */
+ hidden = xfce_rc_read_bool_entry (rc, applications[i], FALSE);
+
+ /* add the application name */
+ xfce_tray_manager_application_add (plugin->manager, applications[i], hidden);
+ }
+
+ /* cleanup */
+ g_strfreev (applications);
+ }
+ }
+
+ /* close the rc file */
+ xfce_rc_close (rc);
+ }
+ }
+}
+
+
+
+static void
+xfce_tray_plugin_write (XfceTrayPlugin *plugin)
+{
+ gchar *file;
+ GSList *applications, *li;
+ XfceRc *rc;
+ XfceTrayApplication *application;
+
+ /* get rc file name, create it if needed */
+ file = xfce_panel_plugin_save_location (plugin->panel_plugin, TRUE);
+
+ if (G_LIKELY (file))
+ {
+ /* open the file, writable */
+ rc = xfce_rc_simple_open (file, FALSE);
+
+ /* cleanup */
+ g_free (file);
+
+ if (G_LIKELY (rc))
+ {
+ /* save global plugin settings */
+ xfce_rc_set_group (rc, "Global");
+
+ /* write setting */
+ xfce_rc_write_bool_entry (rc, "ShowFrame", plugin->show_frame);
+
+ if (G_LIKELY (plugin->manager))
+ {
+ /* save the list of known applications and their visibility */
+ xfce_rc_set_group (rc, "Applications");
+
+ /* get the list of known applications */
+ applications = xfce_tray_manager_application_list (plugin->manager, FALSE);
+
+ /* save their state */
+ for (li = applications; li != NULL; li = li->next)
+ {
+ application = li->data;
+
+ if (G_LIKELY (application->name))
+ xfce_rc_write_bool_entry (rc, application->name, application->hidden);
+ }
+ }
+
+ /* close the rc file */
+ xfce_rc_close (rc);
+ }
+ }
+}
+
+
+
+static void
+xfce_tray_plugin_free (XfceTrayPlugin *plugin)
+{
+ /* free slice */
+ panel_slice_free (XfceTrayPlugin, plugin);
+}
+
+
+
+static void
+xfce_tray_plugin_construct (XfcePanelPlugin *panel_plugin)
+{
+ XfceTrayPlugin *plugin;
+
+ /* create the tray panel plugin */
+ plugin = xfce_tray_plugin_new (panel_plugin);
+
+ /* set the action widgets and show configure */
+ xfce_panel_plugin_add_action_widget (panel_plugin, plugin->frame);
+ xfce_panel_plugin_add_action_widget (panel_plugin, plugin->tray);
+ xfce_panel_plugin_menu_show_configure (panel_plugin);
+
+ /* connect signals */
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "screen-position-changed",
+ G_CALLBACK (xfce_tray_plugin_screen_position_changed), plugin);
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "orientation-changed",
+ G_CALLBACK (xfce_tray_plugin_orientation_changed), plugin);
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "size-changed",
+ G_CALLBACK (xfce_tray_plugin_size_changed), plugin);
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "save",
+ G_CALLBACK (xfce_tray_plugin_write), plugin);
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "free-data",
+ G_CALLBACK (xfce_tray_plugin_free), plugin);
+ g_signal_connect_swapped (G_OBJECT (panel_plugin), "configure-plugin",
+ G_CALLBACK (xfce_tray_dialogs_configure), plugin);
+}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,42 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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 __XFCE_TRAY_PLUGIN_H__
+#define __XFCE_TRAY_PLUGIN_H__
+
+typedef struct _XfceTrayPlugin XfceTrayPlugin;
+
+struct _XfceTrayPlugin
+{
+ /* panel plugin */
+ XfcePanelPlugin *panel_plugin;
+
+ /* tray manager */
+ XfceTrayManager *manager;
+
+ /* widgets */
+ GtkWidget *frame;
+ GtkWidget *tray;
+
+ /* properties */
+ guint show_frame : 1;
+};
+
+
+#endif /* !__XFCE_TRAY_PLUGIN_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,655 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4panel/xfce-arrow-button.h>
+#include <libxfce4panel/xfce-panel-macros.h>
+
+#include "xfce-tray-manager.h"
+#include "xfce-tray-widget.h"
+
+#define XFCE_TRAY_WIDGET_BUTTON_SIZE (16)
+#define XFCE_TRAY_WIDGET_SPACING (1)
+#define XFCE_TRAY_WIDGET_OFFSCREEN (-9999)
+#define XFCE_TRAY_WIDGET_IS_HORIZONTAL(obj) ((obj)->arrow_position == GTK_ARROW_LEFT || (obj)->arrow_position == GTK_ARROW_RIGHT)
+#define XFCE_TRAY_WIDGET_IS_SOUTH_EAST(obj) ((obj)->arrow_position == GTK_ARROW_RIGHT || (obj)->arrow_position == GTK_ARROW_DOWN)
+#define XFCE_TRAY_WIDGET_GET_ORIENTATION(obj) (XFCE_TRAY_WIDGET_IS_HORIZONTAL (obj) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL)
+#define XFCE_TRAY_WIDGET_SWAP_INT(x,y) G_STMT_START{ gint __v = x; x = y; y = __v; }G_STMT_END
+
+
+
+/* prototypes */
+static void xfce_tray_widget_class_init (XfceTrayWidgetClass *klass);
+static void xfce_tray_widget_init (XfceTrayWidget *tray);
+static void xfce_tray_widget_finalize (GObject *object);
+static void xfce_tray_widget_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void xfce_tray_widget_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void xfce_tray_widget_style_set (GtkWidget *widget,
+ GtkStyle *previous_style);
+static void xfce_tray_widget_map (GtkWidget *widget);
+static gint xfce_tray_widget_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray);
+static void xfce_tray_widget_button_clicked (GtkToggleButton *button,
+ XfceTrayWidget *tray);
+static gint xfce_tray_widget_compare_function (gconstpointer a,
+ gconstpointer b);
+static void xfce_tray_widget_icon_added (XfceTrayManager *manager,
+ GtkWidget *icon,
+ XfceTrayWidget *tray);
+static void xfce_tray_widget_icon_removed (XfceTrayManager *manager,
+ GtkWidget *icon,
+ XfceTrayWidget *tray);
+
+
+
+struct _XfceTrayWidgetClass
+{
+ GtkContainerClass __parent__;
+};
+
+struct _XfceTrayWidget
+{
+ GtkContainer __parent__;
+
+ /* tray manager of this tray */
+ XfceTrayManager *manager;
+
+ /* arrow toggle button */
+ GtkWidget *button;
+
+ /* all the icons packed in this box */
+ GSList *childeren;
+
+ /* counters for the icons in the list */
+ guint n_childeren;
+ guint n_hidden_childeren;
+
+ /* whether hidden icons are visible */
+ guint all_visible : 1;
+
+ /* reqested icon size */
+ guint req_child_size;
+
+ /* properties */
+ guint lines;
+ GtkArrowType arrow_position;
+};
+
+
+
+static GObjectClass *xfce_tray_widget_parent_class;
+
+
+
+GType
+xfce_tray_widget_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (GTK_TYPE_CONTAINER,
+ I_("XfceTrayWidget"),
+ sizeof (XfceTrayWidgetClass),
+ (GClassInitFunc) xfce_tray_widget_class_init,
+ sizeof (XfceTrayWidget),
+ (GInstanceInitFunc) xfce_tray_widget_init,
+ 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+xfce_tray_widget_class_init (XfceTrayWidgetClass *klass)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *gtkwidget_class;
+ GtkContainerClass *gtkcontainer_class;
+
+ /* determine the parent type class */
+ xfce_tray_widget_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfce_tray_widget_finalize;
+
+ gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->size_request = xfce_tray_widget_size_request;
+ gtkwidget_class->size_allocate = xfce_tray_widget_size_allocate;
+ gtkwidget_class->style_set = xfce_tray_widget_style_set;
+ gtkwidget_class->expose_event = xfce_tray_widget_expose_event;
+ gtkwidget_class->map = xfce_tray_widget_map;
+
+ gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
+ gtkcontainer_class->add = NULL;
+ gtkcontainer_class->remove = NULL;
+}
+
+
+
+static void
+xfce_tray_widget_init (XfceTrayWidget *tray)
+{
+ GTK_WIDGET_SET_FLAGS (tray, GTK_NO_WINDOW);
+
+ /* initialize */
+ tray->childeren = NULL;
+ tray->button = NULL;
+ tray->manager = NULL;
+
+ tray->n_childeren = 0;
+ tray->n_hidden_childeren = 0;
+
+ tray->all_visible = FALSE;
+ tray->req_child_size = 1;
+
+ tray->lines = 1;
+ tray->arrow_position = GTK_ARROW_LEFT;
+}
+
+
+
+static void
+xfce_tray_widget_finalize (GObject *object)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (object);
+
+ /* free the child list */
+ g_slist_free (tray->childeren);
+
+ /* release the manager */
+ g_object_unref (G_OBJECT (tray->manager));
+
+ G_OBJECT_CLASS (xfce_tray_widget_parent_class)->finalize (object);
+}
+
+
+
+static void
+xfce_tray_widget_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+ gint width, height, size;
+ gint req_child_size, n_childeren;
+ gint columns;
+
+ /* get the requested sizes */
+ gtk_widget_get_size_request (widget, &width, &height);
+
+ /* get the size we can not change */
+ size = (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray) ? height : width);
+
+ /* calculate the requested child size */
+ req_child_size = (size - (XFCE_TRAY_WIDGET_SPACING * (tray->lines - 1))) / tray->lines;
+
+ /* save the requested child size */
+ tray->req_child_size = req_child_size;
+
+ /* number of icons in the tray */
+ n_childeren = tray->n_childeren;
+ if (!tray->all_visible)
+ n_childeren -= tray->n_hidden_childeren;
+
+ /* number of columns in the tray */
+ columns = n_childeren / tray->lines;
+ if (n_childeren > (columns * tray->lines))
+ columns++;
+
+ /* calculate the tray size we can set */
+ size = (req_child_size * columns) + (XFCE_TRAY_WIDGET_SPACING * MAX (columns - 1, 0));
+
+ /* add the hidden button when visible */
+ if (tray->n_hidden_childeren > 0)
+ {
+ size += XFCE_TRAY_WIDGET_BUTTON_SIZE;
+
+ /* space between the button and the icons */
+ if (columns > 0)
+ size += XFCE_TRAY_WIDGET_SPACING;
+ }
+
+ /* set the other size */
+ if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
+ width = size;
+ else
+ height = size;
+
+ /* set your request width and height */
+ requisition->width = width;
+ requisition->height = height;
+}
+
+
+
+static void
+xfce_tray_widget_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+ GSList *li;
+ GtkWidget *child;
+ GtkAllocation child_allocation;
+ gint n = 0, i = 0;
+ gint x_offset = 0;
+
+ /* set the widget allocation */
+ widget->allocation = *allocation;
+
+ /* allocation for the arrow button */
+ if (tray->n_hidden_childeren > 0)
+ {
+ /* set the coordinates and default size */
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = child_allocation.height = XFCE_TRAY_WIDGET_BUTTON_SIZE;
+
+ /* set the offset for the icons */
+ x_offset = XFCE_TRAY_WIDGET_BUTTON_SIZE + XFCE_TRAY_WIDGET_SPACING;
+
+ /* position the button on the other side of the tray */
+ if (XFCE_TRAY_WIDGET_IS_SOUTH_EAST (tray))
+ {
+ /* set the coordinates to the other side of the tray */
+ if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
+ child_allocation.x += allocation->width - XFCE_TRAY_WIDGET_BUTTON_SIZE;
+ else
+ child_allocation.y += allocation->height - XFCE_TRAY_WIDGET_BUTTON_SIZE;
+ }
+
+ /* set the width or height to the allocated size */
+ if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
+ child_allocation.height = allocation->height;
+ else
+ child_allocation.width = allocation->width;
+
+ /* position the arrow button */
+ gtk_widget_size_allocate (tray->button, &child_allocation);
+ }
+
+ /* position all the icons */
+ for (li = tray->childeren; li != NULL; li = li->next, i++)
+ {
+ /* get the child */
+ child = li->data;
+
+ /* handle hidden icons */
+ if (!tray->all_visible && i < tray->n_hidden_childeren)
+ {
+ /* put the widget offscreen */
+ child_allocation.x = child_allocation.y = XFCE_TRAY_WIDGET_OFFSCREEN;
+ }
+ else
+ {
+ /* position of the child on the tray */
+ child_allocation.x = (tray->req_child_size + XFCE_TRAY_WIDGET_SPACING) * (n / tray->lines) + x_offset;
+ child_allocation.y = (tray->req_child_size + XFCE_TRAY_WIDGET_SPACING) * (n % tray->lines);
+
+ /* increase counter */
+ n++;
+
+ /* swap coordinates on a vertical panel */
+ if (!XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
+ XFCE_TRAY_WIDGET_SWAP_INT (child_allocation.x, child_allocation.y);
+
+ /* invert the icon order if the arrow button position is right or down */
+ if (tray->arrow_position == GTK_ARROW_RIGHT)
+ child_allocation.x = allocation->width - child_allocation.x - tray->req_child_size;
+ else if (tray->arrow_position == GTK_ARROW_DOWN)
+ child_allocation.y = allocation->height - child_allocation.y - tray->req_child_size;
+
+ /* add the tray coordinates */
+ child_allocation.x += allocation->x + XFCE_TRAY_WIDGET_SPACING;
+ child_allocation.y += allocation->y + XFCE_TRAY_WIDGET_SPACING;
+ }
+
+ /* set the child width and height */
+ child_allocation.width = child_allocation.height = tray->req_child_size - 2 * XFCE_TRAY_WIDGET_SPACING;
+
+ /* send the child allocation */
+ gtk_widget_size_allocate (child, &child_allocation);
+ }
+}
+
+
+
+static gint
+xfce_tray_widget_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+
+ /* expose the button, because it doesn't have its own window */
+ gtk_container_propagate_expose (GTK_CONTAINER (widget), tray->button, event);
+
+ return FALSE;
+}
+
+
+
+static void
+xfce_tray_widget_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+ GSList *li;
+
+ /* set the button style */
+ if (tray->button)
+ gtk_widget_set_style (tray->button, widget->style);
+
+ /* send the style to all the childeren */
+ for (li = tray->childeren; li != NULL; li = li->next)
+ gtk_widget_set_style (GTK_WIDGET (li->data), widget->style);
+
+ /* invoke the parent */
+ GTK_WIDGET_CLASS (xfce_tray_widget_parent_class)->style_set (widget, previous_style);
+}
+
+
+
+static void
+xfce_tray_widget_map (GtkWidget *widget)
+{
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+
+ /* we've been mapped */
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+ /* create the arrow button (needs a mapped tray before the parent is set) */
+ tray->button = xfce_arrow_button_new (tray->arrow_position);
+ GTK_WIDGET_UNSET_FLAGS (tray->button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
+ gtk_button_set_focus_on_click (GTK_BUTTON (tray->button), FALSE);
+ g_signal_connect (G_OBJECT (tray->button), "clicked", G_CALLBACK (xfce_tray_widget_button_clicked), tray);
+ gtk_widget_set_parent (tray->button, widget);
+ gtk_widget_show (tray->button);
+}
+
+
+
+static void
+xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray)
+{
+ GtkArrowType arrow_type;
+
+ /* get the origional arrow type */
+ arrow_type = tray->arrow_position;
+
+ /* invert the arrow direction when the button is toggled */
+ if (tray->all_visible)
+ {
+ if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
+ arrow_type = (arrow_type == GTK_ARROW_LEFT ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
+ else
+ arrow_type = (arrow_type == GTK_ARROW_UP ? GTK_ARROW_DOWN : GTK_ARROW_UP);
+ }
+
+ /* set the arrow type */
+ xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (tray->button), arrow_type);
+}
+
+
+
+static void
+xfce_tray_widget_button_clicked (GtkToggleButton *button,
+ XfceTrayWidget *tray)
+{
+ /* set the new visible state */
+ tray->all_visible = gtk_toggle_button_get_active (button);
+
+ /* set the button arrow */
+ xfce_tray_widget_button_set_arrow (tray);
+
+ /* update the tray */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
+}
+
+
+
+static gint
+xfce_tray_widget_compare_function (gconstpointer a,
+ gconstpointer b)
+{
+ gboolean a_hidden, b_hidden;
+ const gchar *a_wmname, *b_wmname;
+
+ /* get hidden state */
+ a_hidden = xfce_tray_manager_application_get_hidden (GTK_WIDGET (a));
+ b_hidden = xfce_tray_manager_application_get_hidden (GTK_WIDGET (b));
+
+ /* sort hidden icons before visible ones */
+ if (a_hidden != b_hidden)
+ return (a_hidden ? -1 : 1);
+
+ /* get the window names */
+ a_wmname = xfce_tray_manager_application_get_name (GTK_WIDGET (a));
+ b_wmname = xfce_tray_manager_application_get_name (GTK_WIDGET (b));
+
+ /* return when one of them has no name */
+ if (G_UNLIKELY (!a_wmname || !b_wmname))
+ return (a_wmname == b_wmname ? 0 : (!a_wmname ? -1 : 1));
+
+ return strcmp (a_wmname, b_wmname);
+}
+
+
+
+static void
+xfce_tray_widget_icon_added (XfceTrayManager *manager,
+ GtkWidget *icon,
+ XfceTrayWidget *tray)
+{
+ gboolean hidden;
+
+ g_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
+ g_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
+ g_return_if_fail (GTK_IS_WIDGET (icon));
+
+ /* add the icon to the list */
+ tray->childeren = g_slist_insert_sorted (tray->childeren, icon, xfce_tray_widget_compare_function);
+
+ /* increase counter */
+ tray->n_childeren++;
+
+ /* whether this icon could be hidden */
+ hidden = xfce_tray_manager_application_get_hidden (icon);
+
+ /* increase hidden counter */
+ if (hidden)
+ tray->n_hidden_childeren++;
+
+ /* show the icon */
+ gtk_widget_show (icon);
+
+ /* set the parent window */
+ gtk_widget_set_parent (icon, GTK_WIDGET (tray));
+}
+
+
+
+static void
+xfce_tray_widget_icon_removed (XfceTrayManager *manager,
+ GtkWidget *icon,
+ XfceTrayWidget *tray)
+{
+ g_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
+ g_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
+ g_return_if_fail (GTK_IS_WIDGET (icon));
+
+ /* decrease counter */
+ tray->n_childeren--;
+
+ /* remove the child from the list */
+ tray->childeren = g_slist_remove (tray->childeren, icon);
+
+ /* handle hidden icons */
+ if (xfce_tray_manager_application_get_hidden (icon))
+ {
+ /* decrease hidden counter */
+ tray->n_hidden_childeren--;
+
+ /* collapse the hidden button */
+ if (tray->n_hidden_childeren == 0)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tray->button), FALSE);
+ }
+
+ /* update the tray */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
+}
+
+
+
+GtkWidget *
+xfce_tray_widget_new_for_screen (GdkScreen *screen,
+ GtkArrowType arrow_position,
+ GError **error)
+{
+ XfceTrayWidget *tray = NULL;
+ XfceTrayManager *manager;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* new tray manager */
+ manager = xfce_tray_manager_new ();
+
+ /* register the manager for this screen */
+ if (G_LIKELY (xfce_tray_manager_register (manager, screen, error) == TRUE))
+ {
+ /* create a tray */
+ tray = g_object_new (XFCE_TYPE_TRAY_WIDGET, NULL);
+
+ /* set the manager */
+ tray->manager = manager;
+
+ /* set the orientations */
+ tray->arrow_position = arrow_position;
+ xfce_tray_manager_set_orientation (manager, XFCE_TRAY_WIDGET_GET_ORIENTATION (tray));
+
+ /* manager signals */
+ g_signal_connect (G_OBJECT (manager), "tray-icon-added", G_CALLBACK (xfce_tray_widget_icon_added), tray);
+ g_signal_connect (G_OBJECT (manager), "tray-icon-removed", G_CALLBACK (xfce_tray_widget_icon_removed), tray);
+ //g_signal_connect (G_OBJECT (manager), "tray-message-sent", G_CALLBACK (xfce_tray_widget_message_sent), tray);
+ //g_signal_connect (G_OBJECT (manager), "tray-message-cancelled", G_CALLBACK (xfce_tray_widget_message_cancelled), tray);
+ //g_signal_connect (G_OBJECT (manager), "tray-lost-selection", G_CALLBACK (xfce_tray_widget_lost_selection), tray);
+ }
+ else
+ {
+ /* release the manager */
+ g_object_unref (G_OBJECT (manager));
+ }
+
+ return GTK_WIDGET (tray);
+}
+
+
+
+void
+xfce_tray_widget_sort (XfceTrayWidget *tray)
+{
+ GSList *li;
+ guint n_hidden_childeren = 0;
+
+ /* sort the list */
+ tray->childeren = g_slist_sort (tray->childeren, xfce_tray_widget_compare_function);
+
+ /* count the number of hidden items again */
+ for (li = tray->childeren; li != NULL; li = li->next)
+ {
+ /* increase counter or break (hidden items are in the beginning of the list) */
+ if (xfce_tray_manager_application_get_hidden (GTK_WIDGET (li->data)))
+ n_hidden_childeren++;
+ else
+ break;
+ }
+
+ /* update if changed */
+ if (tray->n_hidden_childeren != n_hidden_childeren)
+ {
+ /* collapse the button if there are no hidden childeren */
+ if (n_hidden_childeren == 0)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tray->button), FALSE);
+
+ /* set new value */
+ tray->n_hidden_childeren = n_hidden_childeren;
+
+ /* update the tray */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
+ }
+}
+
+
+
+XfceTrayManager *
+xfce_tray_widget_get_manager (XfceTrayWidget *tray)
+{
+ g_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), NULL);
+
+ return tray->manager;
+}
+
+
+
+void
+xfce_tray_widget_set_arrow_position (XfceTrayWidget *tray,
+ GtkArrowType arrow_position)
+{
+ g_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
+
+ if (G_LIKELY (tray->arrow_position != arrow_position))
+ {
+ /* set property */
+ tray->arrow_position = arrow_position;
+
+ /* set orientation of the manager */
+ xfce_tray_manager_set_orientation (tray->manager, XFCE_TRAY_WIDGET_GET_ORIENTATION (tray));
+
+ /* set the arrow on the button */
+ xfce_tray_widget_button_set_arrow (tray);
+
+ /* update the tray */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
+ }
+}
+
+
+
+void
+xfce_tray_widget_set_lines (XfceTrayWidget *tray,
+ guint lines)
+{
+ g_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
+ g_return_if_fail (lines >= 1);
+
+ /* set property */
+ tray->lines = lines;
+}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
___________________________________________________________________
Name: keywords
+ Id
Added: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h (rev 0)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h 2007-09-02 11:47:54 UTC (rev 26037)
@@ -0,0 +1,49 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * 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 __XFCE_TRAY_WIDGET_H__
+#define __XFCE_TRAY_WIDGET_H__
+
+typedef struct _XfceTrayWidgetClass XfceTrayWidgetClass;
+typedef struct _XfceTrayWidget XfceTrayWidget;
+
+#define XFCE_TYPE_TRAY_WIDGET (xfce_tray_widget_get_type ())
+#define XFCE_TRAY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_TRAY_WIDGET, XfceTrayWidget))
+#define XFCE_TRAY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_TRAY_WIDGET, XfceTrayWidgetClass))
+#define XFCE_IS_TRAY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_TRAY_WIDGET))
+#define XFCE_IS_TRAY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_TRAY_WIDGET))
+#define XFCE_TRAY_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_TRAY_WIDGET, XfceTrayWidgetClass))
+
+GType xfce_tray_widget_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+GtkWidget *xfce_tray_widget_new_for_screen (GdkScreen *screen,
+ GtkArrowType arrow_position,
+ GError **error) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
+void xfce_tray_widget_sort (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+
+XfceTrayManager *xfce_tray_widget_get_manager (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+
+void xfce_tray_widget_set_arrow_position (XfceTrayWidget *tray,
+ GtkArrowType arrow_position) G_GNUC_INTERNAL;
+
+void xfce_tray_widget_set_lines (XfceTrayWidget *tray,
+ guint lines) G_GNUC_INTERNAL;
+
+#endif /* !__XFCE_TRAY_WIDGET_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
___________________________________________________________________
Name: keywords
+ Id
Modified: xfce4-panel/trunk/po/POTFILES.in
===================================================================
--- xfce4-panel/trunk/po/POTFILES.in 2007-09-01 21:36:32 UTC (rev 26036)
+++ xfce4-panel/trunk/po/POTFILES.in 2007-09-02 11:47:54 UTC (rev 26037)
@@ -33,7 +33,10 @@
plugins/pager/pager.c
plugins/separator/separator.c
plugins/showdesktop/showdesktop.c
-plugins/systray/systray.c
+plugins/systray/xfce-tray-plugin.c
+plugins/systray/xfce-tray-dialogs.c
+plugins/systray/xfce-tray-widget.c
+plugins/systray/xfce-tray-manager.c
plugins/tasklist/tasklist.c
plugins/tasklist/tasklist-dialogs.c
plugins/windowlist/windowlist.c
Modified: xfce4-panel/trunk/po/ar.po
===================================================================
--- xfce4-panel/trunk/po/ar.po 2007-09-01 21:36:32 UTC (rev 26036)
+++ xfce4-panel/trunk/po/ar.po 2007-09-02 11:47:54 UTC (rev 26037)
@@ -7,7 +7,7 @@
msgstr ""
"Project-Id-Version: xfce4-panel\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-06 21:54+0200\n"
+"POT-Creation-Date: 2007-09-02 13:40+0200\n"
"PO-Revision-Date: 2007-02-02 10:45+0200\n"
"Last-Translator: Mohamed Magdy <alnokta at yahoo.com>\n"
"Language-Team: Arabeyes Translation & Documentation <admin at arabeyes.org>\n"
@@ -55,40 +55,40 @@
msgid "An item was unexpectedly removed: \"%s\"."
msgstr "لقد ازيل عنصر بصورة غير متوقعة: \"%s\"."
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:594
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:602
#, c-format
msgid "Remove \"%s\"?"
msgstr "ازل \"%s\"?"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:608
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:616
msgid ""
"The item will be removed from the panel and its configuration will be lost."
msgstr ""
#. configure, hide by default
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:823
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:825
msgid "Properties"
msgstr "خصائص"
#. about item, hide by default
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:840
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:842
msgid "About"
msgstr "حول"
#. move
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:852
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:854
msgid "Move"
msgstr "انقل"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:871
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:873
msgid "Remove"
msgstr "ازل"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:888
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:890
msgid "Add New Item"
msgstr "أضف شيء جديد"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:899 ../panel/panel.c:696
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:901 ../panel/panel.c:696
#: ../mcs-plugin/xfce4-panel-manager.desktop.in.h:1
msgid "Customize Panel"
msgstr "خصص الشريط"
@@ -303,8 +303,10 @@
msgstr "محرر"
#. appearance settings
+#. appearance
#. Button Layout
-#: ../panel/panel-dialogs.c:1427 ../plugins/clock/clock-dialog.c:481
+#: ../panel/panel-dialogs.c:1427 ../plugins/clock/clock-dialog.c:480
+#: ../plugins/systray/xfce-tray-dialogs.c:238
#: ../plugins/tasklist/tasklist-dialogs.c:183
#: ../plugins/windowlist/windowlist-dialog.c:190
msgid "Appearance"
@@ -372,62 +374,64 @@
msgid "Quit + Lock screen"
msgstr "/_إغلاق الشاشة"
-#: ../plugins/clock/clock-dialog.c:346
+#: ../plugins/clock/clock-dialog.c:345
msgid "Custom"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:400
+#: ../plugins/clock/clock-dialog.c:399
#, fuzzy
msgid "Display _seconds"
msgstr "اعرض الثواني"
-#: ../plugins/clock/clock-dialog.c:409
+#: ../plugins/clock/clock-dialog.c:408
msgid "Use 24-_hour clock"
msgstr "استخدم ساعة ال 24"
-#: ../plugins/clock/clock-dialog.c:415
+#: ../plugins/clock/clock-dialog.c:414
#, fuzzy
msgid "Sho_w AM/PM"
msgstr "اظهر صباحاً/مساء"
-#: ../plugins/clock/clock-dialog.c:424
+#: ../plugins/clock/clock-dialog.c:423
msgid "True _binary clock"
msgstr ""
#. create dialog
-#: ../plugins/clock/clock-dialog.c:466
+#: ../plugins/clock/clock-dialog.c:465
#: ../plugins/clock/clock.desktop.in.in.h:1
msgid "Clock"
msgstr "الساعة"
-#: ../plugins/clock/clock-dialog.c:491
+#: ../plugins/clock/clock-dialog.c:490
msgid "Analog"
msgstr "عقارب"
-#: ../plugins/clock/clock-dialog.c:492
+#: ../plugins/clock/clock-dialog.c:491
msgid "Binary"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:493
+#: ../plugins/clock/clock-dialog.c:492
msgid "Digital"
msgstr "رقمية"
-#: ../plugins/clock/clock-dialog.c:494
+#: ../plugins/clock/clock-dialog.c:493
#, fuzzy
msgid "LCD"
msgstr "لمبة"
-#: ../plugins/clock/clock-dialog.c:499 ../plugins/systray/systray.c:402
+#. show frame
+#: ../plugins/clock/clock-dialog.c:498
+#: ../plugins/systray/xfce-tray-dialogs.c:244
msgid "Show _frame"
msgstr ""
#. tooltip settings
-#: ../plugins/clock/clock-dialog.c:506
+#: ../plugins/clock/clock-dialog.c:505
msgid "Tooltip Format"
msgstr ""
#. clock settings
-#: ../plugins/clock/clock-dialog.c:532
+#: ../plugins/clock/clock-dialog.c:531
msgid "Clock Options"
msgstr "خيارات الساعة"
@@ -563,36 +567,36 @@
msgid "Switch workspaces using the mouse wheel"
msgstr ""
-#: ../plugins/separator/separator.c:397
+#: ../plugins/separator/separator.c:409
#: ../plugins/separator/separator.desktop.in.in.h:2
#, fuzzy
msgid "Separator or Spacing"
msgstr "فاصل"
-#: ../plugins/separator/separator.c:418
+#: ../plugins/separator/separator.c:430
#, fuzzy
msgid "Separator Style"
msgstr "فاصل"
#. space
-#: ../plugins/separator/separator.c:425
+#: ../plugins/separator/separator.c:437
msgid "_Empty Space"
msgstr ""
-#: ../plugins/separator/separator.c:434
+#: ../plugins/separator/separator.c:446
msgid "_Expanding Empty Space"
msgstr ""
-#: ../plugins/separator/separator.c:443
+#: ../plugins/separator/separator.c:455
msgid "_Line"
msgstr ""
-#: ../plugins/separator/separator.c:452
+#: ../plugins/separator/separator.c:464
#, fuzzy
msgid "_Handle"
msgstr "موقع"
-#: ../plugins/separator/separator.c:461
+#: ../plugins/separator/separator.c:473
msgid "_Dots"
msgstr ""
@@ -604,20 +608,29 @@
msgid "Hide windows and show desktop"
msgstr "اخفي النوافذ واظهر سطح المكتب"
-#: ../plugins/systray/systray.c:69 ../plugins/systray/systray.c:84
+#. create a dialog
+#. create dialog
+#: ../plugins/systray/xfce-tray-plugin.c:71
+#: ../plugins/systray/xfce-tray-dialogs.c:224
+#: ../plugins/systray/systray.desktop.in.in.h:2
+msgid "System Tray"
+msgstr "صينية النظام"
+
+#: ../plugins/systray/xfce-tray-plugin.c:97
msgid "There is already a system tray running on this screen"
msgstr "هناك صينية نظام تعمل مسبقا على الشاشة"
-#: ../plugins/systray/systray.c:90
+#. applications
+#: ../plugins/systray/xfce-tray-dialogs.c:251
+#, fuzzy
+msgid "Hidden Applications"
+msgstr "إختر أمر"
+
+#: ../plugins/systray/xfce-tray-manager.c:431
#, c-format
-msgid "Unable to register system tray: %s"
-msgstr "لم أتمكن من تسجيل صينية النظام: %s"
+msgid "Failed to acquire manager selection for screen %d"
+msgstr ""
-#: ../plugins/systray/systray.c:378
-#: ../plugins/systray/systray.desktop.in.in.h:2
-msgid "System Tray"
-msgstr "صينية النظام"
-
#: ../plugins/tasklist/tasklist-dialogs.c:157
#: ../plugins/tasklist/tasklist-dialogs.c:224
#: ../plugins/tasklist/tasklist.desktop.in.in.h:2
@@ -805,102 +818,105 @@
msgid "Xfce 4 Panel Manager"
msgstr "مدير أشرطة اكسفس 4"
+#~ msgid "Unable to register system tray: %s"
+#~ msgstr "لم أتمكن من تسجيل صينية النظام: %s"
+
#, fuzzy
-msgid ""
-"\n"
-" Xfce Panel %s\n"
-"\n"
-" Part of the Xfce Desktop Environment\n"
-" http://www.xfce.org\n"
-"\n"
-" Licensed under the GNU GPL.\n"
-"\n"
-msgstr ""
-"\n"
-"The Xfce Panel\n"
-"نسخة %s\n"
-"\n"
-"جزء من الواجهة الرسومية Xfce\n"
-"http://www.xfce.org\n"
-"\n"
-"Licensed under the GNU GPL.\n"
-"\n"
+#~ msgid ""
+#~ "\n"
+#~ " Xfce Panel %s\n"
+#~ "\n"
+#~ " Part of the Xfce Desktop Environment\n"
+#~ " http://www.xfce.org\n"
+#~ "\n"
+#~ " Licensed under the GNU GPL.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "The Xfce Panel\n"
+#~ "نسخة %s\n"
+#~ "\n"
+#~ "جزء من الواجهة الرسومية Xfce\n"
+#~ "http://www.xfce.org\n"
+#~ "\n"
+#~ "Licensed under the GNU GPL.\n"
+#~ "\n"
-msgid ""
-" Usage: %s [OPTIONS]\n"
-"\n"
-msgstr ""
-"الاستخدام: %s [OPTIONS]\n"
-"\n"
+#~ msgid ""
+#~ " Usage: %s [OPTIONS]\n"
+#~ "\n"
+#~ msgstr ""
+#~ "الاستخدام: %s [OPTIONS]\n"
+#~ "\n"
#, fuzzy
-msgid "%A %d %B %Y"
-msgstr "%A, %d %B %Y"
+#~ msgid "%A %d %B %Y"
+#~ msgstr "%A, %d %B %Y"
-msgid "Error in command \"%s\""
-msgstr "خطأ في الأمر \"%s\""
+#~ msgid "Error in command \"%s\""
+#~ msgstr "خطأ في الأمر \"%s\""
#, fuzzy
-msgid "This item has not yet been configured"
-msgstr "ﻻ يحوي على خيرات أعداد"
+#~ msgid "This item has not yet been configured"
+#~ msgstr "ﻻ يحوي على خيرات أعداد"
-msgid "Default"
-msgstr "تلقائي"
+#~ msgid "Default"
+#~ msgstr "تلقائي"
-msgid "File management"
-msgstr "متصفح الملفات"
+#~ msgid "File management"
+#~ msgstr "متصفح الملفات"
-msgid "Utilities"
-msgstr "وسائل"
+#~ msgid "Utilities"
+#~ msgstr "وسائل"
-msgid "Games"
-msgstr "ألعاب"
+#~ msgid "Games"
+#~ msgstr "ألعاب"
-msgid "Help browser"
-msgstr "متصفح المساعدة"
+#~ msgid "Help browser"
+#~ msgstr "متصفح المساعدة"
-msgid "Multimedia"
-msgstr "وسائط متعددة"
+#~ msgid "Multimedia"
+#~ msgstr "وسائط متعددة"
-msgid "Network"
-msgstr "شبكة"
+#~ msgid "Network"
+#~ msgstr "شبكة"
-msgid "Graphics"
-msgstr "رسومية"
+#~ msgid "Graphics"
+#~ msgstr "رسومية"
-msgid "Printer"
-msgstr "طابعة"
+#~ msgid "Printer"
+#~ msgstr "طابعة"
-msgid "Productivity"
-msgstr "إنتاجية"
+#~ msgid "Productivity"
+#~ msgstr "إنتاجية"
-msgid "Office"
-msgstr "المكتب"
+#~ msgid "Office"
+#~ msgstr "المكتب"
-msgid "Sound"
-msgstr "صوت"
+#~ msgid "Sound"
+#~ msgstr "صوت"
-msgid "Terminal"
-msgstr "سطر اﻷوامر"
+#~ msgid "Terminal"
+#~ msgstr "سطر اﻷوامر"
-msgid "Development"
-msgstr "التطوير"
+#~ msgid "Development"
+#~ msgstr "التطوير"
-msgid "Select image file"
-msgstr "اختر ملف صورة"
+#~ msgid "Select image file"
+#~ msgstr "اختر ملف صورة"
-msgid "Select command"
-msgstr "إختر أمر"
+#~ msgid "Select command"
+#~ msgstr "إختر أمر"
-msgid "Other..."
-msgstr "آخر"
+#~ msgid "Other..."
+#~ msgstr "آخر"
-msgid "Select file"
-msgstr "إختر ملف"
+#~ msgid "Select file"
+#~ msgstr "إختر ملف"
#, fuzzy
-msgid "_Draw Separator"
-msgstr "فاصل"
+#~ msgid "_Draw Separator"
+#~ msgstr "فاصل"
-msgid "_Expand"
-msgstr "_افرد"
+#~ msgid "_Expand"
+#~ msgstr "_افرد"
Modified: xfce4-panel/trunk/po/az.po
===================================================================
--- xfce4-panel/trunk/po/az.po 2007-09-01 21:36:32 UTC (rev 26036)
+++ xfce4-panel/trunk/po/az.po 2007-09-02 11:47:54 UTC (rev 26037)
@@ -7,7 +7,7 @@
msgstr ""
"Project-Id-Version: xfce4-panel 4.4.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-06 21:54+0200\n"
+"POT-Creation-Date: 2007-09-02 13:40+0200\n"
"PO-Revision-Date: 2005-09-29 20:16+0900\n"
"Last-Translator: Mətin Əmirov <metin at karegen.com>\n"
"Language-Team: Azerbaijani <translation-team-az at lists.sourceforge.net>\n"
@@ -57,43 +57,43 @@
msgid "An item was unexpectedly removed: \"%s\"."
msgstr ""
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:594
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:602
#, fuzzy, c-format
msgid "Remove \"%s\"?"
msgstr "Sil"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:608
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:616
msgid ""
"The item will be removed from the panel and its configuration will be lost."
msgstr ""
#. configure, hide by default
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:823
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:825
msgid "Properties"
msgstr ""
#. about item, hide by default
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:840
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:842
msgid "About"
msgstr ""
#. move
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:852
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:854
#, fuzzy
msgid "Move"
msgstr "Sil"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:871
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:873
#, fuzzy
msgid "Remove"
msgstr "Sil"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:888
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:890
#, fuzzy
msgid "Add New Item"
msgstr "Yeni üzv əlavə et"
-#: ../libxfce4panel/xfce-panel-plugin-iface.c:899 ../panel/panel.c:696
+#: ../libxfce4panel/xfce-panel-plugin-iface.c:901 ../panel/panel.c:696
#: ../mcs-plugin/xfce4-panel-manager.desktop.in.h:1
msgid "Customize Panel"
msgstr ""
@@ -309,8 +309,10 @@
msgstr "Editor"
#. appearance settings
+#. appearance
#. Button Layout
-#: ../panel/panel-dialogs.c:1427 ../plugins/clock/clock-dialog.c:481
+#: ../panel/panel-dialogs.c:1427 ../plugins/clock/clock-dialog.c:480
+#: ../plugins/systray/xfce-tray-dialogs.c:238
#: ../plugins/tasklist/tasklist-dialogs.c:183
#: ../plugins/windowlist/windowlist-dialog.c:190
msgid "Appearance"
@@ -380,62 +382,64 @@
msgid "Quit + Lock screen"
msgstr "/Ekranı _qıfılla"
-#: ../plugins/clock/clock-dialog.c:346
+#: ../plugins/clock/clock-dialog.c:345
msgid "Custom"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:400
+#: ../plugins/clock/clock-dialog.c:399
msgid "Display _seconds"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:409
+#: ../plugins/clock/clock-dialog.c:408
msgid "Use 24-_hour clock"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:415
+#: ../plugins/clock/clock-dialog.c:414
#, fuzzy
msgid "Sho_w AM/PM"
msgstr "GƏ/GS"
-#: ../plugins/clock/clock-dialog.c:424
+#: ../plugins/clock/clock-dialog.c:423
msgid "True _binary clock"
msgstr ""
#. create dialog
-#: ../plugins/clock/clock-dialog.c:466
+#: ../plugins/clock/clock-dialog.c:465
#: ../plugins/clock/clock.desktop.in.in.h:1
#, fuzzy
msgid "Clock"
msgstr "Qıfılla"
-#: ../plugins/clock/clock-dialog.c:491
+#: ../plugins/clock/clock-dialog.c:490
msgid "Analog"
msgstr "Analoq"
-#: ../plugins/clock/clock-dialog.c:492
+#: ../plugins/clock/clock-dialog.c:491
msgid "Binary"
msgstr ""
-#: ../plugins/clock/clock-dialog.c:493
+#: ../plugins/clock/clock-dialog.c:492
msgid "Digital"
msgstr "Dijital"
-#: ../plugins/clock/clock-dialog.c:494
+#: ../plugins/clock/clock-dialog.c:493
#, fuzzy
msgid "LCD"
msgstr "LED"
-#: ../plugins/clock/clock-dialog.c:499 ../plugins/systray/systray.c