[Xfce4-commits] <xfce4-panel:devel> Half-baked cleanup of the systray plugin.
Nick Schermer
nick at xfce.org
Tue Aug 11 20:30:52 CEST 2009
Updating branch refs/heads/devel
to aaa1410fdfaf0ee32cc7ea2785230784d9144066 (commit)
from 463e65dd583384be90cf63e4a11e6c150d6a2206 (commit)
commit aaa1410fdfaf0ee32cc7ea2785230784d9144066
Author: Nick Schermer <nick at xfce.org>
Date: Sun Mar 22 20:32:41 2009 +0100
Half-baked cleanup of the systray plugin.
Renamed from files and going to remove the tray widget layer.
Also added support for transparent tray icons, but this
is not fully working yet.
plugins/systray/Makefile.am | 43 +-
plugins/systray/systray-dialog.glade | 21 +-
plugins/systray/systray-manager.c | 932 ++++++++++++++++++++
plugins/systray/systray-manager.h | 72 ++
...xfce-tray-marshal.list => systray-marshal.list} | 0
plugins/systray/systray.c | 582 ++++++++++++
plugins/systray/systray.h | 44 +
plugins/systray/xfce-tray-dialogs.c | 491 -----------
plugins/systray/xfce-tray-dialogs.h | 25 -
plugins/systray/xfce-tray-manager.c | 889 -------------------
plugins/systray/xfce-tray-manager.h | 76 --
plugins/systray/xfce-tray-plugin.c | 497 -----------
plugins/systray/xfce-tray-plugin.h | 42 -
plugins/systray/xfce-tray-widget.c | 847 ------------------
plugins/systray/xfce-tray-widget.h | 69 --
15 files changed, 1671 insertions(+), 2959 deletions(-)
diff --git a/plugins/systray/Makefile.am b/plugins/systray/Makefile.am
index 0071670..f907bbb 100644
--- a/plugins/systray/Makefile.am
+++ b/plugins/systray/Makefile.am
@@ -11,25 +11,24 @@ plugindir = \
plugin_LTLIBRARIES = \
libsystray.la
-
+
libsystray_built_sources = \
- xfce-tray-marshal.c \
- xfce-tray-marshal.h
+ systray-dialog_glade.h \
+ systray-marshal.c \
+ systray-marshal.h
libsystray_la_SOURCES = \
$(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
+ systray.c \
+ systray.h \
+ systray-manager.c \
+ systray-manager.h
libsystray_la_CFLAGS = \
$(LIBX11_CFLAGS) \
$(GTK_CFLAGS) \
+ $(EXO_CFLAGS) \
+ $(XFCONF_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(LIBXFCE4UI_CFLAGS) \
$(PLATFORM_CFLAGS)
@@ -44,6 +43,8 @@ libsystray_la_LIBADD = \
$(top_builddir)/libxfce4panel/libxfce4panel.la \
$(LIBX11_LIBS) \
$(GTK_LIBS) \
+ $(EXO_LIBS) \
+ $(XFCONF_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
$(LIBXFCE4UI_LIBS)
@@ -63,12 +64,13 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
EXTRA_DIST = \
$(desktop_in_in_files) \
- xfce-tray-marshal.list
-
+ systray-dialog.glade \
+ systray-marshal.list
+
DISTCLEANFILES = \
$(desktop_DATA) \
$(desktop_in_files)
-
+
#
# Rules to auto-generate built sources
#
@@ -79,12 +81,15 @@ BUILT_SOURCES = \
DISTCLEANFILES += \
$(libsystray_built_sources)
-xfce-tray-marshal.h: xfce-tray-marshal.list Makefile
- glib-genmarshal --header --internal --prefix=_xfce_tray_marshal $< > $@
+systray-marshal.h: systray-marshal.list Makefile
+ glib-genmarshal --header --internal --prefix=_systray_marshal $< > $@
+
+systray-marshal.c: systray-marshal.list Makefile
+ echo "#include \"systray-marshal.h\"" > $@ \
+ && glib-genmarshal --prefix=_systray_marshal --body $< >> $@
-xfce-tray-marshal.c: xfce-tray-marshal.list Makefile
- echo "#include \"xfce-tray-marshal.h\"" > $@ \
- && glib-genmarshal --prefix=_xfce_tray_marshal --body $< >> $@
+systray-dialog_glade.h: systray-dialog.glade
+ exo-csource --static --strip-comments --strip-content --name=systray_dialog_glade $< >$@
endif
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/plugins/systray/systray-dialog.glade b/plugins/systray/systray-dialog.glade
index 90d3221..66b9fc3 100644
--- a/plugins/systray/systray-dialog.glade
+++ b/plugins/systray/systray-dialog.glade
@@ -42,7 +42,7 @@
<property name="xalign">0</property>
<property name="label" translatable="yes">_Number of rows:</property>
<property name="use_underline">True</property>
- <property name="mnemonic_widget">style-num-rows</property>
+ <property name="mnemonic_widget">rows</property>
</object>
<packing>
<property name="expand">False</property>
@@ -50,9 +50,11 @@
</packing>
</child>
<child>
- <object class="GtkSpinButton" id="style-num-rows">
+ <object class="GtkSpinButton" id="rows">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="shadow_type">none</property>
+ <property name="adjustment">rows-adjustment</property>
<property name="numeric">True</property>
</object>
<packing>
@@ -66,7 +68,7 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="style-show-frame">
+ <object class="GtkCheckButton" id="show-frame">
<property name="label" translatable="yes">Show _frame</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -103,12 +105,12 @@
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
- <property name="top_padding">6</property>
<property name="left_padding">12</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="border_width">6</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
@@ -116,6 +118,8 @@
<object class="GtkTreeView" id="applications-treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="headers_clickable">False</property>
+ <property name="rules_hint">True</property>
</object>
</child>
</object>
@@ -152,6 +156,8 @@
<property name="use_stock">True</property>
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
@@ -168,4 +174,11 @@
<action-widget response="0">close-button</action-widget>
</action-widgets>
</object>
+ <object class="GtkAdjustment" id="rows-adjustment">
+ <property name="value">1</property>
+ <property name="lower">1</property>
+ <property name="upper">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">2</property>
+ </object>
</interface>
diff --git a/plugins/systray/systray-manager.c b/plugins/systray/systray-manager.c
new file mode 100644
index 0000000..2999885
--- /dev/null
+++ b/plugins/systray/systray-manager.c
@@ -0,0 +1,932 @@
+/* $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-2009 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/libxfce4panel.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "systray-manager.h"
+#include "systray-marshal.h"
+
+
+
+#define XFCE_SYSTRAY_MANAGER_REQUEST_DOCK 0
+#define XFCE_SYSTRAY_MANAGER_BEGIN_MESSAGE 1
+#define XFCE_SYSTRAY_MANAGER_CANCEL_MESSAGE 2
+
+#define XFCE_SYSTRAY_MANAGER_ORIENTATION_HORIZONTAL 0
+#define XFCE_SYSTRAY_MANAGER_ORIENTATION_VERTICAL 1
+
+
+
+static void systray_manager_finalize (GObject *object);
+static void systray_manager_remove_socket (gpointer key,
+ gpointer value,
+ gpointer user_data);
+static GdkFilterReturn systray_manager_window_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer user_data);
+static GdkFilterReturn systray_manager_handle_client_message_opcode (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
+static GdkFilterReturn systray_manager_handle_client_message_message_data (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
+static void systray_manager_handle_begin_message (SystrayManager *manager,
+ XClientMessageEvent *xevent);
+static void systray_manager_handle_cancel_message (SystrayManager *manager,
+ XClientMessageEvent *xevent);
+static void systray_manager_handle_dock_request (SystrayManager *manager,
+ XClientMessageEvent *xevent);
+static gboolean systray_manager_handle_undock_request (GtkSocket *socket,
+ gpointer user_data);
+static void systray_manager_set_visual (SystrayManager *manager);
+static void systray_manager_message_free (SystrayMessage *message);
+static void systray_manager_message_remove_from_list (SystrayManager *manager,
+ XClientMessageEvent *xevent);
+
+
+
+enum
+{
+ ICON_ADDED,
+ ICON_REMOVED,
+ MESSAGE_SENT,
+ MESSAGE_CANCELLED,
+ LOST_SELECTION,
+ LAST_SIGNAL
+};
+
+struct _SystrayManagerClass
+{
+ GObjectClass __parent__;
+};
+
+struct _SystrayManager
+{
+ 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;
+};
+
+struct _SystrayMessage
+{
+ /* message string */
+ gchar *string;
+
+ /* message id */
+ glong id;
+
+ /* x11 window */
+ Window window;
+
+ /* numb3rs */
+ glong length;
+ glong remaining_length;
+ glong timeout;
+};
+
+
+
+static guint systray_manager_signals[LAST_SIGNAL];
+static GQuark xwindow_quark = 0;
+
+
+
+XFCE_PANEL_DEFINE_TYPE (SystrayManager, systray_manager, G_TYPE_OBJECT)
+
+
+
+static void
+systray_manager_class_init (SystrayManagerClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = systray_manager_finalize;
+
+ systray_manager_signals[ICON_ADDED] =
+ g_signal_new (I_("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);
+
+ systray_manager_signals[ICON_REMOVED] =
+ g_signal_new (I_("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);
+
+ systray_manager_signals[MESSAGE_SENT] =
+ g_signal_new (I_("message-sent"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ _systray_marshal_VOID__OBJECT_STRING_LONG_LONG,
+ G_TYPE_NONE, 4,
+ GTK_TYPE_SOCKET,
+ G_TYPE_STRING,
+ G_TYPE_LONG,
+ G_TYPE_LONG);
+
+ systray_manager_signals[MESSAGE_CANCELLED] =
+ g_signal_new (I_("message-cancelled"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ _systray_marshal_VOID__OBJECT_LONG,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_SOCKET,
+ G_TYPE_LONG);
+
+ systray_manager_signals[LOST_SELECTION] =
+ g_signal_new (I_("lost-selection"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* initialize quark */
+ xwindow_quark = g_quark_from_static_string ("systray-manager-xwindow");
+}
+
+
+
+static void
+systray_manager_init (SystrayManager *manager)
+{
+ /* initialize */
+ manager->invisible = NULL;
+ manager->orientation = GTK_ORIENTATION_HORIZONTAL;
+ manager->messages = NULL;
+
+ /* create new sockets table */
+ manager->sockets = g_hash_table_new (NULL, NULL);
+}
+
+
+
+GQuark
+systray_manager_error_quark (void)
+{
+ static GQuark q = 0;
+
+ if (q == 0)
+ q = g_quark_from_static_string ("systray-manager-error-quark");
+
+ return q;
+}
+
+
+
+static void
+systray_manager_finalize (GObject *object)
+{
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (object);
+
+ /* destroy the hash table */
+ g_hash_table_destroy (manager->sockets);
+
+ if (manager->messages)
+ {
+ /* cleanup all pending messages */
+ g_slist_foreach (manager->messages,
+ (GFunc) systray_manager_message_free, NULL);
+
+ /* free the list */
+ g_slist_free (manager->messages);
+ }
+
+ G_OBJECT_CLASS (systray_manager_parent_class)->finalize (object);
+}
+
+
+
+SystrayManager *
+systray_manager_new (void)
+{
+ return g_object_new (XFCE_TYPE_SYSTRAY_MANAGER, NULL);
+}
+
+
+
+gboolean
+systray_manager_check_running (GdkScreen *screen)
+{
+ gchar *selection_name;
+ GdkDisplay *display;
+ Atom selection_atom;
+
+ panel_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
+systray_manager_register (SystrayManager *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;
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager), FALSE);
+ panel_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ panel_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);
+
+ /* set the invisible window and take a reference */
+ manager->invisible = g_object_ref (G_OBJECT (invisible));
+
+ /* set the visial property for transparent tray icons */
+ if (gtk_check_version (2, 16, 0) == NULL)
+ systray_manager_set_visual (manager);
+
+ /* 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);
+
+ /* system_tray_request_dock and selectionclear */
+ gdk_window_add_filter (invisible->window, systray_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, systray_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),
+ systray_manager_handle_client_message_message_data, manager);
+ }
+ else
+ {
+ /* release the invisible */
+ g_object_unref (G_OBJECT (manager->invisible));
+ manager->invisible = NULL;
+
+ /* desktroy the invisible window */
+ gtk_widget_destroy (invisible);
+
+ /* set an error */
+ g_set_error (error, XFCE_SYSTRAY_MANAGER_ERROR,
+ XFCE_SYSTRAY_MANAGER_ERROR_SELECTION_FAILED,
+ _("Failed to acquire manager selection for screen %d"),
+ screen_number);
+ }
+
+ return succeed;
+}
+
+
+
+static void
+systray_manager_remove_socket (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+ GtkSocket *socket = GTK_SOCKET (value);
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (GTK_IS_SOCKET (socket));
+
+ /* properly undock from the tray */
+ g_signal_emit (manager, systray_manager_signals[ICON_REMOVED], 0, socket);
+}
+
+
+
+void
+systray_manager_unregister (SystrayManager *manager)
+{
+ GdkDisplay *display;
+ GtkWidget *invisible = manager->invisible;
+ GdkWindow *owner;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+
+ /* leave when there is no invisible window */
+ if (invisible == NULL)
+ return;
+
+ panel_return_if_fail (GTK_IS_INVISIBLE (invisible));
+ panel_return_if_fail (GTK_WIDGET_REALIZED (invisible));
+ panel_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 */
+ owner = gdk_selection_owner_get_for_display (display, manager->selection_atom);
+ if (owner == 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, systray_manager_window_filter, manager);
+
+ /* remove all sockets from the hash table */
+ g_hash_table_foreach (manager->sockets, systray_manager_remove_socket, manager);
+
+ /* destroy and unref the invisible window */
+ manager->invisible = NULL;
+ gtk_widget_destroy (invisible);
+ g_object_unref (G_OBJECT (invisible));
+}
+
+
+
+static GdkFilterReturn
+systray_manager_window_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XEvent *xevent = (XEvent *)xev;
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager), GDK_FILTER_CONTINUE);
+
+ if (xevent->type == ClientMessage)
+ {
+ if (xevent->xclient.message_type == manager->opcode_atom
+ && xevent->xclient.data.l[1] == XFCE_SYSTRAY_MANAGER_REQUEST_DOCK)
+ {
+ /* dock a tray icon */
+ systray_manager_handle_dock_request (manager, (XClientMessageEvent *) xevent);
+
+ return GDK_FILTER_REMOVE;
+ }
+ }
+ else if (xevent->type == SelectionClear)
+ {
+ /* emit the signal */
+ g_signal_emit (manager, systray_manager_signals[LOST_SELECTION], 0);
+
+ /* unregister the manager */
+ systray_manager_unregister (manager);
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+
+static GdkFilterReturn
+systray_manager_handle_client_message_opcode (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XClientMessageEvent *xev;
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager), GDK_FILTER_REMOVE);
+
+ /* cast to x11 event */
+ xev = (XClientMessageEvent *) xevent;
+
+ switch (xev->data.l[1])
+ {
+ case XFCE_SYSTRAY_MANAGER_REQUEST_DOCK:
+ /* handled in systray_manager_window_filter () */
+ break;
+
+ case XFCE_SYSTRAY_MANAGER_BEGIN_MESSAGE:
+ systray_manager_handle_begin_message (manager, xev);
+ return GDK_FILTER_REMOVE;
+
+ case XFCE_SYSTRAY_MANAGER_CANCEL_MESSAGE:
+ systray_manager_handle_cancel_message (manager, xev);
+ return GDK_FILTER_REMOVE;
+
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+
+static GdkFilterReturn
+systray_manager_handle_client_message_message_data (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ XClientMessageEvent *xev = xevent;
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+ GSList *li;
+ SystrayMessage *message;
+ glong length;
+ GtkSocket *socket;
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_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, systray_manager_signals[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 */
+ systray_manager_message_free (message);
+ }
+
+ /* stop searching */
+ break;
+ }
+ }
+
+ return GDK_FILTER_REMOVE;
+}
+
+
+
+static void
+systray_manager_handle_begin_message (SystrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkSocket *socket;
+ SystrayMessage *message;
+ glong length, timeout, id;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+
+ /* 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 */
+ systray_manager_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, systray_manager_signals[MESSAGE_SENT], 0,
+ socket, "", id, timeout);
+ }
+ else
+ {
+ /* create new structure */
+ message = g_slice_new0 (SystrayMessage);
+
+ /* 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
+systray_manager_handle_cancel_message (SystrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkSocket *socket;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+
+ /* remove the same message from the list */
+ systray_manager_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, systray_manager_signals[MESSAGE_CANCELLED], 0,
+ socket, xevent->data.l[2]);
+ }
+}
+
+
+
+static void
+systray_manager_handle_dock_request (SystrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GtkWidget *socket;
+ Window *xwindow;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+
+ /* 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 ();
+
+ /* 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_qdata_full (G_OBJECT (socket), xwindow_quark, xwindow, g_free);
+
+ /* add the icon to the tray */
+ g_signal_emit (manager, systray_manager_signals[ICON_ADDED], 0, socket);
+
+ /* check if the widget has been attached. if the widget has no
+ toplevel window, we cannot set the socket id. */
+ 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 (systray_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
+ {
+ /* warning */
+ g_warning ("No parent window set, destroying socket");
+
+ /* not attached successfully, destroy it */
+ gtk_widget_destroy (socket);
+ }
+}
+
+
+
+static gboolean
+systray_manager_handle_undock_request (GtkSocket *socket,
+ gpointer user_data)
+{
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+ Window *xwindow;
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager), FALSE);
+
+ /* emit signal that the socket will be removed */
+ g_signal_emit (manager, systray_manager_signals[ICON_REMOVED], 0, socket);
+
+ /* get the xwindow */
+ xwindow = g_object_get_qdata (G_OBJECT (socket), xwindow_quark);
+
+ /* remove the socket from the list */
+ g_hash_table_remove (manager->sockets, GUINT_TO_POINTER (*xwindow));
+
+ /* unset object data */
+ g_object_set_qdata (G_OBJECT (socket), xwindow_quark, NULL);
+
+ /* destroy the socket */
+ return FALSE;
+}
+
+
+
+static void
+systray_manager_set_visual (SystrayManager *manager)
+{
+ GdkDisplay *display;
+ Visual *xvisual;
+ Atom visual_atom;
+ gulong data[1];
+ GdkColormap *colormap;
+ GdkScreen *screen;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (GTK_IS_INVISIBLE (manager->invisible));
+ panel_return_if_fail (GDK_IS_WINDOW (manager->invisible->window));
+
+ /* get invisible display and screen */
+ display = gtk_widget_get_display (manager->invisible);
+ screen = gtk_invisible_get_screen (GTK_INVISIBLE (manager->invisible));
+
+ /* get the xatom for the visual property */
+ visual_atom = gdk_x11_get_xatom_by_name_for_display (display,
+ "_NET_SYSTEM_TRAY_VISUAL");
+
+ if (gtk_widget_is_composited (manager->invisible)
+ && gdk_screen_get_rgba_visual (screen) != NULL
+ && gdk_display_supports_composite (display))
+ {
+ /* get the rgba visual */
+ xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (screen));
+ }
+ else
+ {
+ /* use the default visual for the screen */
+ colormap = gdk_screen_get_default_colormap (screen);
+ xvisual = GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (colormap));
+ }
+
+ data[0] = XVisualIDFromVisual (xvisual);
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (manager->invisible->window),
+ visual_atom,
+ XA_VISUALID, 32,
+ PropModeReplace,
+ (guchar *) &data, 1);
+}
+
+
+
+void
+systray_manager_set_orientation (SystrayManager *manager,
+ GtkOrientation orientation)
+{
+ GdkDisplay *display;
+ Atom orientation_atom;
+ gulong data[1];
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (GTK_IS_INVISIBLE (manager->invisible));
+ panel_return_if_fail (GDK_IS_WINDOW (manager->invisible->window));
+
+ 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_SYSTRAY_MANAGER_ORIENTATION");
+
+ /* set the data we're going to send to x */
+ data[0] = (manager->orientation == GTK_ORIENTATION_HORIZONTAL ?
+ XFCE_SYSTRAY_MANAGER_ORIENTATION_HORIZONTAL
+ : XFCE_SYSTRAY_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);
+ }
+}
+
+
+
+gchar *
+systray_manager_get_application_name (GtkWidget *socket)
+{
+ gchar *name = NULL;
+ GdkDisplay *display;
+ gint succeed;
+ XTextProperty xprop;
+ Window *xwindow;
+
+ /* get the xwindow */
+ xwindow = g_object_get_qdata (G_OBJECT (socket), xwindow_quark);
+
+ if (G_LIKELY (xwindow != NULL))
+ {
+ /* 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))
+ {
+ /* get the lowercase name if it's utf-8 valid */
+ if (G_LIKELY (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL)))
+ name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
+
+ /* cleanup */
+ XFree (xprop.value);
+ }
+ }
+ }
+
+ return name;
+}
+
+
+
+/**
+ * tray messages
+ **/
+static void
+systray_manager_message_free (SystrayMessage *message)
+{
+ /* cleanup */
+ g_free (message->string);
+
+ /* remove slice */
+ g_slice_free (SystrayMessage, message);
+}
+
+
+
+static void
+systray_manager_message_remove_from_list (SystrayManager *manager,
+ XClientMessageEvent *xevent)
+{
+ GSList *li;
+ SystrayMessage *message;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+
+ /* 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 */
+ systray_manager_message_free (message);
+
+ break;
+ }
+ }
+}
diff --git a/plugins/systray/systray-manager.h b/plugins/systray/systray-manager.h
new file mode 100644
index 0000000..455761f
--- /dev/null
+++ b/plugins/systray/systray-manager.h
@@ -0,0 +1,72 @@
+/* $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-2009 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 __SYSTRAY_MANAGER_H__
+#define __SYSTRAY_MANAGER_H__
+
+#include <gtk/gtk.h>
+
+typedef struct _SystrayManagerClass SystrayManagerClass;
+typedef struct _SystrayManager SystrayManager;
+typedef struct _SystrayMessage SystrayMessage;
+
+#define XFCE_TYPE_SYSTRAY_MANAGER (systray_manager_get_type ())
+#define XFCE_SYSTRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SYSTRAY_MANAGER, SystrayManager))
+#define XFCE_SYSTRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SYSTRAY_MANAGER, SystrayManagerClass))
+#define XFCE_IS_SYSTRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SYSTRAY_MANAGER))
+#define XFCE_IS_SYSTRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SYSTRAY_MANAGER))
+#define XFCE_SYSTRAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SYSTRAY_MANAGER, SystrayManagerClass))
+#define XFCE_SYSTRAY_MANAGER_ERROR (systray_manager_error_quark())
+
+
+
+enum
+{
+ XFCE_SYSTRAY_MANAGER_ERROR_SELECTION_FAILED
+};
+
+
+
+GType systray_manager_get_type (void) G_GNUC_CONST;
+
+void systray_manager_register_type (GTypeModule *type_module);
+
+GQuark systray_manager_error_quark (void);
+
+SystrayManager *systray_manager_new (void) G_GNUC_MALLOC;
+
+gboolean systray_manager_check_running (GdkScreen *screen);
+
+gboolean systray_manager_register (SystrayManager *manager,
+ GdkScreen *screen,
+ GError **error);
+
+void systray_manager_unregister (SystrayManager *manager);
+
+void systray_manager_set_orientation (SystrayManager *manager,
+ GtkOrientation orientation);
+
+gchar *systray_manager_get_application_name (GtkWidget *socket) G_GNUC_MALLOC;
+
+
+#endif /* !__SYSTRAY_MANAGER_H__ */
diff --git a/plugins/systray/xfce-tray-marshal.list b/plugins/systray/systray-marshal.list
similarity index 100%
rename from plugins/systray/xfce-tray-marshal.list
rename to plugins/systray/systray-marshal.list
diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c
new file mode 100644
index 0000000..9368dd6
--- /dev/null
+++ b/plugins/systray/systray.c
@@ -0,0 +1,582 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
+ * Copyright (c) 2007-2009 Nick Schermer <nick at xfce.org>
+ *
+ * This library 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 library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+#include <common/panel-private.h>
+#include <xfconf/xfconf.h>
+#include <exo/exo.h>
+
+#include "systray.h"
+#include "systray-manager.h"
+#include "systray-dialog_glade.h"
+
+
+
+static void systray_plugin_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void systray_plugin_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void systray_plugin_construct (XfcePanelPlugin *panel_plugin);
+static void systray_plugin_free_data (XfcePanelPlugin *panel_plugin);
+static void systray_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, gint screen_position);
+static void systray_plugin_orientation_changed (XfcePanelPlugin *panel_plugin, GtkOrientation orientation);
+static gboolean systray_plugin_size_changed (XfcePanelPlugin *panel_plugin, gint size);
+static void systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
+
+static void systray_plugin_reallocate (SystrayPlugin *plugin);
+
+static void systray_plugin_icon_added (SystrayManager *manager, GtkWidget *icon, SystrayPlugin *plugin);
+static void systray_plugin_icon_removed (SystrayManager *manager, GtkWidget *icon, SystrayPlugin *plugin);
+static void systray_plugin_lost_selection (SystrayManager *manager, SystrayPlugin *plugin);
+
+
+
+struct _SystrayPluginClass
+{
+ XfcePanelPluginClass __parent__;
+};
+
+struct _SystrayPlugin
+{
+ XfcePanelPlugin __parent__;
+
+ /* systray manager */
+ SystrayManager *manager;
+
+ /* xfconf channnel */
+ XfconfChannel *channel;
+
+ /* widgets */
+ GtkWidget *frame;
+ GtkWidget *fixed;
+ GtkWidget *button;
+
+ GSList *children;
+
+ guint show_hidden : 1;
+
+ /* settings */
+ guint rows;
+ guint show_frame : 1;
+};
+
+enum _SystrayChildState
+{
+ CHILD_VISIBLE, /* always visible */
+ CHILD_AUTO_HIDE, /* hidden when tray is collapsed */
+ CHILD_DISABLED /* never show this icon */
+};
+
+struct _SystrayChild
+{
+ /* the status icon */
+ GtkWidget *icon;
+
+ /* application name */
+ gchar *name;
+
+ /* child state */
+ SystrayChildState state;
+};
+
+enum
+{
+ PROP_0,
+ PROP_ROWS,
+ PROP_SHOW_FRAME
+};
+
+
+
+/* define the plugin */
+XFCE_PANEL_DEFINE_PLUGIN (SystrayPlugin, systray_plugin,
+ systray_manager_register_type)
+
+
+
+static void
+systray_plugin_class_init (SystrayPluginClass *klass)
+{
+ XfcePanelPluginClass *plugin_class;
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->get_property = systray_plugin_get_property;
+ gobject_class->set_property = systray_plugin_set_property;
+
+ plugin_class = XFCE_PANEL_PLUGIN_CLASS (klass);
+ plugin_class->construct = systray_plugin_construct;
+ plugin_class->free_data = systray_plugin_free_data;
+ plugin_class->size_changed = systray_plugin_size_changed;
+ plugin_class->screen_position_changed = systray_plugin_screen_position_changed;
+ plugin_class->configure_plugin = systray_plugin_configure_plugin;
+ plugin_class->orientation_changed = systray_plugin_orientation_changed;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ROWS,
+ g_param_spec_uint ("rows",
+ NULL, NULL,
+ 1, 10, 1,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_FRAME,
+ g_param_spec_boolean ("show-frame",
+ NULL, NULL,
+ FALSE,
+ EXO_PARAM_READWRITE));
+}
+
+
+
+static void
+systray_plugin_init (SystrayPlugin *plugin)
+{
+ plugin->manager = NULL;
+ plugin->rows = 1;
+ plugin->show_frame = FALSE;
+
+ /* initialize xfconf */
+ xfconf_init (NULL);
+
+ /* show configure */
+ xfce_panel_plugin_menu_show_configure (XFCE_PANEL_PLUGIN (plugin));
+
+ /* plugin widgets */
+ plugin->frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (plugin), plugin->frame);
+ gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), GTK_SHADOW_NONE);
+ gtk_widget_show (plugin->frame);
+
+ plugin->fixed = gtk_fixed_new ();
+ gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->fixed);
+ xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->fixed);
+ gtk_widget_show (plugin->fixed);
+
+ plugin->button = xfce_arrow_button_new (GTK_ARROW_NONE);
+ gtk_container_add (GTK_CONTAINER (plugin->fixed), plugin->button);
+ xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->button);
+}
+
+
+
+static void
+systray_plugin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_ROWS:
+ g_value_set_uint (value, plugin->rows);
+ break;
+
+ case PROP_SHOW_FRAME:
+ g_value_set_boolean (value, plugin->show_frame);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+systray_plugin_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_ROWS:
+ plugin->rows = g_value_get_uint (value);
+ systray_plugin_reallocate (plugin);
+ break;
+
+ case PROP_SHOW_FRAME:
+ plugin->show_frame = g_value_get_boolean (value);
+
+ /* set the frame shadow */
+ gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame),
+ plugin->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+systray_plugin_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (widget);
+ GdkScreen *screen;
+ GError *error = NULL;
+
+ if (G_UNLIKELY (plugin->manager != NULL))
+ {
+ /* unregister from this screen */
+ systray_manager_unregister (plugin->manager);
+ g_object_unref (G_OBJECT (plugin->manager));
+ plugin->manager = NULL;
+ }
+
+ /* get the new screen */
+ screen = gtk_widget_get_screen (widget);
+
+ /* check if not another systray is running on this screen */
+ if (G_LIKELY (systray_manager_check_running (screen) == FALSE))
+ {
+ /* create a new manager and register this screen */
+ plugin->manager = systray_manager_new ();
+
+ /* hookup signals */
+ g_signal_connect (G_OBJECT (plugin->manager), "icon-added",
+ G_CALLBACK (systray_plugin_icon_added), plugin);
+ g_signal_connect (G_OBJECT (plugin->manager), "icon-removed",
+ G_CALLBACK (systray_plugin_icon_removed), plugin);
+ g_signal_connect (G_OBJECT (plugin->manager), "lost-selection",
+ G_CALLBACK (systray_plugin_lost_selection), plugin);
+
+ if (!systray_manager_register (plugin->manager, screen, &error))
+ {
+ /* TODO handle error and leave the plugin */
+ g_message ("Failed to register the systray manager %s", error->message);
+ g_error_free (error);
+ }
+ }
+ else
+ {
+ /* TODO, error and leave the plugin */
+ g_message ("already a notification area running");
+ }
+}
+
+
+
+static void
+systray_plugin_construct (XfcePanelPlugin *panel_plugin)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin);
+
+ /* open the xfconf channel */
+ plugin->channel = xfce_panel_plugin_xfconf_channel_new (panel_plugin);
+
+ /* bind the properties */
+ xfconf_g_property_bind (plugin->channel, "/rows",
+ G_TYPE_UINT, plugin, "rows");
+ xfconf_g_property_bind (plugin->channel, "/show-frame",
+ G_TYPE_BOOLEAN, plugin, "show-frame");
+
+ /* monitor screen changes */
+ g_signal_connect (G_OBJECT (plugin), "screen-changed",
+ G_CALLBACK (systray_plugin_screen_changed), NULL);
+
+ /* initialize the screen */
+ systray_plugin_screen_changed (GTK_WIDGET (plugin), NULL);
+}
+
+
+
+static void
+systray_plugin_free_data (XfcePanelPlugin *panel_plugin)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin);
+
+ /* disconnect screen changed signal */
+ g_signal_handlers_disconnect_by_func (G_OBJECT (plugin),
+ systray_plugin_screen_changed, NULL);
+
+ /* release the manager */
+ if (G_LIKELY (plugin->manager))
+ g_object_unref (G_OBJECT (plugin->manager));
+
+ /* release the xfconf channel */
+ if (G_LIKELY (plugin->channel))
+ g_object_unref (G_OBJECT (plugin->channel));
+
+ /* shutdown xfconf */
+ xfconf_shutdown ();
+}
+
+
+
+static void
+systray_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin,
+ gint screen_position)
+{
+
+}
+
+
+
+static void
+systray_plugin_orientation_changed (XfcePanelPlugin *panel_plugin,
+ GtkOrientation orientation)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin);
+
+ /* send the new orientation to the manager */
+ if (G_LIKELY (plugin->manager != NULL))
+ systray_manager_set_orientation (plugin->manager, orientation);
+}
+
+
+
+static gboolean
+systray_plugin_size_changed (XfcePanelPlugin *panel_plugin,
+ gint size)
+{
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_PLUGIN (panel_plugin), FALSE);
+
+ if (xfce_panel_plugin_get_orientation (panel_plugin)
+ == GTK_ORIENTATION_HORIZONTAL)
+ gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), -1, size);
+ else
+ gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), size, -1);
+
+ /* reallocate all the children */
+ systray_plugin_reallocate (XFCE_SYSTRAY_PLUGIN (panel_plugin));
+
+ return TRUE;
+}
+
+
+
+static void
+systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
+{
+ SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin);
+ GtkBuilder *builder;
+ GObject *dialog, *object;
+
+ /* fix gtk builder problem: "Invalid object type XfceTitledDialog" */
+ if (xfce_titled_dialog_get_type () == 0)
+ return;
+
+ builder = gtk_builder_new ();
+ if (gtk_builder_add_from_string (builder, systray_dialog_glade,
+ systray_dialog_glade_length, NULL))
+ {
+ dialog = gtk_builder_get_object (builder, "dialog");
+ g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, builder);
+ xfce_panel_plugin_take_window (panel_plugin, GTK_WINDOW (dialog));
+
+ xfce_panel_plugin_block_menu (panel_plugin);
+ g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify)
+ xfce_panel_plugin_unblock_menu, panel_plugin);
+
+ object = gtk_builder_get_object (builder, "close-button");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ g_signal_connect_swapped (G_OBJECT (object), "clicked",
+ G_CALLBACK (gtk_widget_destroy), dialog);
+
+ object = gtk_builder_get_object (builder, "rows");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ exo_mutual_binding_new (G_OBJECT (plugin), "rows",
+ G_OBJECT (object), "value");
+
+ object = gtk_builder_get_object (builder, "show-frame");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ exo_mutual_binding_new (G_OBJECT (plugin), "show-frame",
+ G_OBJECT (object), "active");
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+ }
+ else
+ {
+ /* release the builder */
+ g_object_unref (G_OBJECT (builder));
+ }
+}
+
+
+
+static void
+systray_plugin_reallocate (SystrayPlugin *plugin)
+{
+ GSList *li;
+ SystrayChild *child;
+ guint n;
+ gint x, y;
+ gint size;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+
+ /* get the icon size from the last allocation of the fixed widget */
+ size = xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin));
+ size = (size - 4) / plugin->rows;
+ if (size < 1)
+ size = 1;
+
+ for (li = plugin->children, n = 0; li != NULL; li = li->next)
+ {
+ child = li->data;
+
+ /* set the size request of the widget */
+ x = size * (n / plugin->rows);
+ y = size * (n % plugin->rows);
+
+ gtk_fixed_move (GTK_FIXED (plugin->fixed), child->icon, x, y);
+ gtk_widget_set_size_request (child->icon, size, size);
+
+ /* increase counter */
+ n++;
+ }
+}
+
+
+
+static gint
+systray_plugin_child_compare (gconstpointer a,
+ gconstpointer b)
+{
+ const SystrayChild *child_a = a;
+ const SystrayChild *child_b = b;
+
+ if (child_a->state == CHILD_DISABLED
+ || child_b->state == CHILD_DISABLED)
+ return 0;
+
+ /* sort auto hide icons before visible ones */
+ if ((child_a->state == CHILD_AUTO_HIDE)
+ != (child_b->state == CHILD_AUTO_HIDE))
+ return ((child_a->state == CHILD_AUTO_HIDE) ? -1 : 1);
+
+ if (!IS_STRING (child_a->name) || !IS_STRING (child_b->name))
+ {
+ if (IS_STRING (child_a->name) == IS_STRING (child_b->name))
+ return 0;
+ else
+ return !IS_STRING (child_a->name) ? -1 : 1;
+ }
+
+ /* sort by name */
+ return strcmp (child_a->name, child_b->name);
+}
+
+
+
+static void
+systray_plugin_icon_added (SystrayManager *manager,
+ GtkWidget *icon,
+ SystrayPlugin *plugin)
+{
+ SystrayChild *child;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+ panel_return_if_fail (plugin->manager == manager);
+ panel_return_if_fail (GTK_IS_WIDGET (icon));
+
+ /* allocate a new child */
+ child = g_slice_new0 (SystrayChild);
+ child->name = systray_manager_get_application_name (icon);
+ child->state = CHILD_VISIBLE;
+ child->icon = icon;
+
+ /* insert the child in the list */
+ plugin->children = g_slist_insert_sorted (plugin->children, child,
+ systray_plugin_child_compare);
+
+ /* put the icon in the widget, offscreen */
+ gtk_fixed_put (GTK_FIXED (plugin->fixed), icon, 0, 0);
+ gtk_widget_show (icon);
+
+ /* allocate the children */
+ systray_plugin_reallocate (plugin);
+}
+
+
+
+static void
+systray_plugin_icon_removed (SystrayManager *manager,
+ GtkWidget *icon,
+ SystrayPlugin *plugin)
+{
+ GSList *li;
+ SystrayChild *child;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+ panel_return_if_fail (plugin->manager == manager);
+ panel_return_if_fail (GTK_IS_WIDGET (icon));
+
+ for (li = plugin->children; li != NULL; li = li->next)
+ {
+ child = li->data;
+
+ if (child->icon == icon)
+ {
+ /* remove from the list */
+ plugin->children = g_slist_remove_link (plugin->children, li);
+
+ /* destroy the widget */
+ gtk_widget_destroy (icon);
+
+ /* cleanup */
+ g_free (child->name);
+ g_slice_free (SystrayChild, child);
+
+ /* reallocate the children */
+ systray_plugin_reallocate (plugin);
+
+ /* done */
+ return;
+ }
+ }
+
+ /* icon removed but not known? weird... */
+ panel_assert_not_reached ();
+}
+
+
+
+static void
+systray_plugin_lost_selection (SystrayManager *manager,
+ SystrayPlugin *plugin)
+{
+ GError error;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
+ panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin));
+ panel_return_if_fail (plugin->manager == manager);
+
+ /* create fake error and show it */
+ error.message = _("Most likely another widget took over the function "
+ "of a notification area. This plugin will close.");
+ xfce_dialog_show_error (gtk_widget_get_screen (GTK_WIDGET (plugin)), &error,
+ _("The notification area lost selection"));
+}
diff --git a/plugins/systray/systray.h b/plugins/systray/systray.h
new file mode 100644
index 0000000..e1cab1b
--- /dev/null
+++ b/plugins/systray/systray.h
@@ -0,0 +1,44 @@
+/* $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 __SYSTRAY_H__
+#define __SYSTRAY_H__
+
+#include <gtk/gtk.h>
+#include <libxfce4panel/libxfce4panel.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SystrayPluginClass SystrayPluginClass;
+typedef struct _SystrayPlugin SystrayPlugin;
+typedef struct _SystrayChild SystrayChild;
+typedef enum _SystrayChildState SystrayChildState;
+
+#define XFCE_TYPE_SYSTRAY_PLUGIN (systray_plugin_get_type ())
+#define XFCE_SYSTRAY_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SYSTRAY_PLUGIN, SystrayPlugin))
+#define XFCE_SYSTRAY_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SYSTRAY_PLUGIN, SystrayPluginClass))
+#define XFCE_IS_SYSTRAY_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SYSTRAY_PLUGIN))
+#define XFCE_IS_SYSTRAY_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SYSTRAY_PLUGIN))
+#define XFCE_SYSTRAY_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SYSTRAY_PLUGIN, SystrayPluginClass))
+
+GType systray_plugin_get_type (void) G_GNUC_CONST;
+
+void systray_plugin_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* !__SYSTRAY_H__ */
diff --git a/plugins/systray/xfce-tray-dialogs.c b/plugins/systray/xfce-tray-dialogs.c
deleted file mode 100644
index f5a7222..0000000
--- a/plugins/systray/xfce-tray-dialogs.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2007-2009 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
-
-#define XFCE_TRAY_DIALOG_ICON_SIZE 22
-
-#include <gtk/gtk.h>
-#include <libxfce4util/libxfce4util.h>
-#include <libxfce4ui/libxfce4ui.h>
-#include <libxfce4panel/libxfce4panel.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,
- 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_n_rows_changed (GtkSpinButton *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;
- guint i;
- gchar *first_occ;
- const gchar *p;
- const gchar *fallback[][2] =
- {
- /* application name , fallback icon name or path */
- { "xfce-mcs-manager", "input-mouse" },
- { "bluetooth-applet", "stock_bluetooth" },
- { "gdl_box", "/opt/google/desktop/resource/gdl_small.png" },
- { "networkmanager applet", "network-workgroup" },
- };
-
- /* return null on no name */
- if (G_UNLIKELY (name == NULL))
- return NULL;
-
- /* 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 (G_LIKELY (icon))
- return icon;
-
- /* try the first part when the name contains a space */
- p = g_utf8_strchr (name, -1, ' ');
- if (p)
- {
- /* get the string before the first occurrence */
- first_occ = g_strndup (name, p - name);
-
- /* try to load the icon from the theme */
- icon = gtk_icon_theme_load_icon (icon_theme, first_occ, XFCE_TRAY_DIALOG_ICON_SIZE, 0, NULL);
-
- /* cleanup */
- g_free (first_occ);
-
- if (icon)
- return icon;
- }
-
- /* find and return a fall-back icon */
- for (i = 0; i < G_N_ELEMENTS (fallback); i++)
- if (strcmp (name, fallback[i][0]) == 0)
- {
- if (g_path_is_absolute (fallback[i][1]))
- {
- return gdk_pixbuf_new_from_file_at_size (fallback[i][1], XFCE_TRAY_DIALOG_ICON_SIZE,
- XFCE_TRAY_DIALOG_ICON_SIZE, NULL);
- }
- else
- {
- return gtk_icon_theme_load_icon (icon_theme, fallback[i][1], XFCE_TRAY_DIALOG_ICON_SIZE,
- 0, NULL);
- }
- }
-
- return NULL;
-}
-
-
-
-static void
-xfce_tray_dialogs_show_frame_toggled (GtkToggleButton *button,
- XfceTrayPlugin *plugin)
-{
- gboolean active;
- gint panel_size;
-
- /* 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;
-
- /* get the panel size */
- panel_size = xfce_panel_plugin_get_size (plugin->panel_plugin);
-
- /* emit size-changed signal */
- g_signal_emit_by_name (G_OBJECT (plugin->panel_plugin), "size-changed", panel_size, &active);
-}
-
-
-
-static void
-xfce_tray_dialogs_n_rows_changed (GtkSpinButton *button,
- XfceTrayPlugin *plugin)
-{
- gint value;
-
- /* get value */
- value = gtk_spin_button_get_value_as_int (button);
-
- /* set rows */
- xfce_tray_widget_set_rows (XFCE_TRAY_WIDGET (plugin->tray), value);
-}
-
-
-
-static void
-xfce_tray_dialogs_treeview_toggled (GtkCellRendererToggle *widget,
- gchar *path,
- GtkWidget *treeview)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *tmp, *name;
- gboolean hidden;
- 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 lower case application name and hidden state */
- gtk_tree_model_get (model, &iter, APPLICATION_NAME, &tmp, APPLICATION_HIDDEN, &hidden, -1);
- name = g_utf8_strdown (tmp, -1);
- g_free (tmp);
-
- /* get tray plugin */
- plugin = g_object_get_data (G_OBJECT (treeview), I_("xfce-tray-plugin"));
-
- if (G_LIKELY (name && plugin))
- {
- /* update the manager */
- xfce_tray_widget_name_update (XFCE_TRAY_WIDGET (plugin->tray), name, !hidden);
-
- /* set the new list value */
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, APPLICATION_HIDDEN, !hidden, -1);
- }
-
- /* cleanup */
- g_free (name);
- }
-}
-
-
-
-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)
-{
- GtkWidget *question;
- GtkListStore *store;
-
- if (response == GTK_RESPONSE_YES)
- {
- /* create question dialog, with hig buttons */
- question = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
- _("Are you sure you want to clear the list of known applications?"));
- gtk_dialog_add_buttons (GTK_DIALOG (question), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
- GTK_STOCK_CLEAR, GTK_RESPONSE_YES, NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (question), GTK_RESPONSE_NO);
-
- /* run dialog */
- if (gtk_dialog_run (GTK_DIALOG (question)) == GTK_RESPONSE_YES)
- {
- /* clear hash table and update tray */
- xfce_tray_widget_clear_name_list (XFCE_TRAY_WIDGET (plugin->tray));
-
- /* clear store */
- store = g_object_get_data (G_OBJECT (dialog), I_("xfce-tray-store"));
- gtk_list_store_clear (store);
- }
-
- /* destroy */
- gtk_widget_destroy (question);
- }
- else
- {
- /* 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;
- GtkWidget *vbox, *label, *hbox, *spin;
- GtkListStore *store;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTreeIter iter;
- GList *names, *li;
- const gchar *name;
- gchar *camelcase;
- gboolean hidden;
- 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_CLEAR, GTK_RESPONSE_YES,
- 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_window_set_default_size (GTK_WINDOW (dialog), 280, 400);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- 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);
-
- /* main vbox */
- dialog_vbox = GTK_DIALOG (dialog)->vbox;
-
- /* appearance */
- frame = xfce_gtk_frame_box_new (_("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);
-
- /* vbox */
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_container_add (GTK_CONTAINER (bin), vbox);
- gtk_widget_show (vbox);
-
- /* show frame */
- button = gtk_check_button_new_with_mnemonic (_("Show _frame"));
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- 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);
-
- /* box */
- hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- /* number of rows */
- label = gtk_label_new_with_mnemonic (_("_Number of rows:"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- /* spin */
- spin = gtk_spin_button_new_with_range (1, 6, 1);
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spin), 0);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), xfce_tray_widget_get_rows (XFCE_TRAY_WIDGET (plugin->tray)));
- g_signal_connect (G_OBJECT (spin), "value-changed", G_CALLBACK (xfce_tray_dialogs_n_rows_changed), plugin);
- gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, FALSE, 0);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
- gtk_widget_show (spin);
-
- /* applications */
- frame = xfce_gtk_frame_box_new (_("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_object_set_data (G_OBJECT (dialog), I_("xfce-tray-store"), store);
-
- /* 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_search_column (GTK_TREE_VIEW (treeview), APPLICATION_NAME);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
- gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (treeview), TRUE);
- 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_spacing (column, 2);
- gtk_tree_view_column_set_expand (column, TRUE);
- gtk_tree_view_column_set_resizable (column, FALSE);
- gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-
- /* renderer for the icon */
- renderer = gtk_cell_renderer_pixbuf_new();
- gtk_cell_renderer_set_fixed_size (renderer, XFCE_TRAY_DIALOG_ICON_SIZE, XFCE_TRAY_DIALOG_ICON_SIZE);
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", APPLICATION_ICON, NULL);
-
- /* renderer for the name */
- 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);
- g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-
- /* renderer for the toggle button */
- 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 */
- names = xfce_tray_widget_name_list (XFCE_TRAY_WIDGET (plugin->tray));
-
- /* add all the application to the list */
- for (li = names; li != NULL; li = li->next)
- {
- name = li->data;
-
- /* create a camel case name of the application */
- camelcase = xfce_tray_dialogs_camel_case (name);
-
- /* whether this name is hidden */
- hidden = xfce_tray_widget_name_hidden (XFCE_TRAY_WIDGET (plugin->tray), name);
-
- /* append the application */
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- APPLICATION_NAME, camelcase,
- APPLICATION_HIDDEN, hidden, -1);
-
- /* cleanup */
- g_free (camelcase);
-
- /* get the application icon */
- pixbuf = xfce_tray_dialogs_icon (icon_theme, name);
-
- if (G_LIKELY (pixbuf))
- {
- /* set the icon */
- gtk_list_store_set (store, &iter, APPLICATION_ICON, pixbuf, -1);
-
- /* release */
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
-
- /* cleanup */
- g_list_free (names);
-
- /* show the dialog */
- gtk_widget_show (dialog);
-}
diff --git a/plugins/systray/xfce-tray-dialogs.h b/plugins/systray/xfce-tray-dialogs.h
deleted file mode 100644
index b135730..0000000
--- a/plugins/systray/xfce-tray-dialogs.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (C) 2007-2009 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_DIALOGS_H__
-#define __XFCE_TRAY_DIALOGS_H__
-
-void xfce_tray_dialogs_configure (XfceTrayPlugin *plugin);
-
-#endif /* !__XFCE_TRAY_DIALOGS_H__ */
diff --git a/plugins/systray/xfce-tray-manager.c b/plugins/systray/xfce-tray-manager.c
deleted file mode 100644
index d0629bf..0000000
--- a/plugins/systray/xfce-tray-manager.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/* $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-2009 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/libxfce4panel.h>
-#include <libxfce4util/libxfce4util.h>
-
-#include "xfce-tray-manager.h"
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-#include "xfce-tray-marshal.h"
-#endif
-
-
-
-#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_finalize (GObject *object);
-static void xfce_tray_manager_remove_socket (gpointer key,
- gpointer value,
- gpointer user_data);
-static GdkFilterReturn xfce_tray_manager_window_filter (GdkXEvent *xev,
- GdkEvent *event,
- gpointer user_data);
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-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);
-#endif
-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);
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-static void xfce_tray_message_free (XfceTrayMessage *message);
-static void xfce_tray_message_remove_from_list (XfceTrayManager *manager,
- XClientMessageEvent *xevent);
-#endif
-
-
-enum
-{
- TRAY_ICON_ADDED,
- TRAY_ICON_REMOVED,
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- TRAY_MESSAGE_SENT,
- TRAY_MESSAGE_CANCELLED,
-#endif
- 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;
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- /* list of pending messages */
- GSList *messages;
-#endif
-
- /* _net_system_tray_opcode atom */
- Atom opcode_atom;
-
- /* _net_system_tray_s%d atom */
- GdkAtom selection_atom;
-};
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-struct _XfceTrayMessage
-{
- /* message string */
- gchar *string;
-
- /* message id */
- glong id;
-
- /* x11 window */
- Window window;
-
- /* numb3rs */
- glong length;
- glong remaining_length;
- glong timeout;
-};
-#endif
-
-
-
-static guint xfce_tray_manager_signals[LAST_SIGNAL];
-
-
-
-G_DEFINE_TYPE (XfceTrayManager, xfce_tray_manager, G_TYPE_OBJECT)
-
-
-
-static void
-xfce_tray_manager_class_init (XfceTrayManagerClass *klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (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);
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- 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);
-#endif
-
- 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->invisible = NULL;
- manager->orientation = GTK_ORIENTATION_HORIZONTAL;
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- manager->messages = NULL;
-#endif
-
- /* 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);
-
- /* destroy the hash table */
- g_hash_table_destroy (manager->sockets);
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- 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);
- }
-#endif
-
- 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;
-
- panel_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;
-
- panel_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), FALSE);
- panel_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
- panel_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);
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
- /* 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);
-#endif
- }
- 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_remove_socket (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- XfceTrayManager *manager = XFCE_TRAY_MANAGER (user_data);
- GtkSocket *socket = GTK_SOCKET (value);
-
- panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- panel_return_if_fail (GTK_IS_SOCKET (socket));
-
- /* properly undock from the tray */
- g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_REMOVED], 0, socket);
-}
-
-
-
-void
-xfce_tray_manager_unregister (XfceTrayManager *manager)
-{
- GdkDisplay *display;
- GtkWidget *invisible = manager->invisible;
-
- /* leave when there is no invisible window */
- if (invisible == NULL)
- return;
-
- panel_return_if_fail (GTK_IS_INVISIBLE (invisible));
- panel_return_if_fail (GTK_WIDGET_REALIZED (invisible));
- panel_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);
-
- /* remove all sockets from the hash table */
- g_hash_table_foreach (manager->sockets, xfce_tray_manager_remove_socket, 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;
-}
-
-
-
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-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);
-
- panel_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;
-
- panel_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 = g_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]);
- }
-}
-#endif
-
-
-
-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);
-
- /* add the icon to the tray */
- g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_ADDED], 0, socket);
-
- /* check if the widget has been attached. if the widget has no
- toplevel window, we cannot set the socket id. */
- 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
- {
- /* warning */
- g_warning ("No parent window set, destroying socket");
-
- /* 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;
-
- panel_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);
-
- /* destroy the socket */
- return FALSE;
-}
-
-
-
-GtkOrientation
-xfce_tray_manager_get_orientation (XfceTrayManager *manager)
-{
- panel_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];
-
- panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- panel_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);
- }
-}
-
-
-
-gchar *
-xfce_tray_manager_get_application_name (GtkWidget *socket)
-{
- gchar *name = NULL;
- GdkDisplay *display;
- gint succeed;
- XTextProperty xprop;
- Window *xwindow;
-
- /* get the xwindow */
- xwindow = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"));
-
- if (G_LIKELY (xwindow))
- {
- /* 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);
- }
-
- /* cleanup */
- XFree (xprop.value);
- }
- }
- }
-
- return name;
-}
-
-
-
-/**
- * tray messages
- **/
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-static void
-xfce_tray_message_free (XfceTrayMessage *message)
-{
- /* cleanup */
- g_free (message->string);
-
- /* remove slice */
- g_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;
- }
- }
-}
-#endif
diff --git a/plugins/systray/xfce-tray-manager.h b/plugins/systray/xfce-tray-manager.h
deleted file mode 100644
index 2cc235a..0000000
--- a/plugins/systray/xfce-tray-manager.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $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-2009 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__
-
-#define XFCE_TRAY_MANAGER_ENABLE_MESSAGES 0
-
-
-
-typedef struct _XfceTrayManagerClass XfceTrayManagerClass;
-typedef struct _XfceTrayManager XfceTrayManager;
-#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
-typedef struct _XfceTrayMessage XfceTrayMessage;
-#endif
-
-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;
-
-GQuark xfce_tray_manager_error_quark (void);
-
-XfceTrayManager *xfce_tray_manager_new (void) G_GNUC_MALLOC;
-
-gboolean xfce_tray_manager_check_running (GdkScreen *screen);
-
-gboolean xfce_tray_manager_register (XfceTrayManager *manager,
- GdkScreen *screen,
- GError **error);
-
-void xfce_tray_manager_unregister (XfceTrayManager *manager);
-
-GtkOrientation xfce_tray_manager_get_orientation (XfceTrayManager *manager);
-
-void xfce_tray_manager_set_orientation (XfceTrayManager *manager,
- GtkOrientation orientation);
-
-gchar *xfce_tray_manager_get_application_name (GtkWidget *socket) G_GNUC_MALLOC;
-
-
-#endif /* !__XFCE_TRAY_MANAGER_H__ */
diff --git a/plugins/systray/xfce-tray-plugin.c b/plugins/systray/xfce-tray-plugin.c
deleted file mode 100644
index fb51269..0000000
--- a/plugins/systray/xfce-tray-plugin.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2007-2009 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 SMALL_PANEL_SIZE (26)
-
-#include <gtk/gtk.h>
-#include <libxfce4util/libxfce4util.h>
-#include <libxfce4panel/libxfce4panel.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 void xfce_tray_plugin_update_position (XfceTrayPlugin *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_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 void
-xfce_tray_plugin_update_position (XfceTrayPlugin *plugin)
-{
- XfceScreenPosition position;
- GdkScreen *screen;
- GdkRectangle geom;
- gint mon, x, y;
- GtkArrowType arrow_type;
-
- panel_return_if_fail (GTK_WIDGET_REALIZED (plugin->panel_plugin));
-
- /* get the plugin position */
- position = xfce_panel_plugin_get_screen_position (plugin->panel_plugin);
-
- /* get the button position */
- switch (position)
- {
- /* horizontal west */
- case XFCE_SCREEN_POSITION_NW_H:
- case XFCE_SCREEN_POSITION_SW_H:
- arrow_type = GTK_ARROW_RIGHT;
- break;
-
- /* horizontal east */
- case XFCE_SCREEN_POSITION_N:
- case XFCE_SCREEN_POSITION_NE_H:
- case XFCE_SCREEN_POSITION_S:
- case XFCE_SCREEN_POSITION_SE_H:
- arrow_type = GTK_ARROW_LEFT;
- break;
-
- /* vertical north */
- case XFCE_SCREEN_POSITION_NW_V:
- case XFCE_SCREEN_POSITION_NE_V:
- arrow_type = GTK_ARROW_DOWN;
- break;
-
- /* vertical south */
- case XFCE_SCREEN_POSITION_W:
- case XFCE_SCREEN_POSITION_SW_V:
- case XFCE_SCREEN_POSITION_E:
- case XFCE_SCREEN_POSITION_SE_V:
- arrow_type = GTK_ARROW_UP;
- break;
-
- /* floating */
- default:
- /* get the screen information */
- screen = gtk_widget_get_screen (GTK_WIDGET (plugin->panel_plugin));
- mon = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (plugin->panel_plugin)->window);
- gdk_screen_get_monitor_geometry (screen, mon, &geom);
- gdk_window_get_root_origin (GTK_WIDGET (plugin->panel_plugin)->window, &x, &y);
-
- /* get the position based on the screen position */
- if (position == XFCE_SCREEN_POSITION_FLOATING_H)
- arrow_type = ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
- else
- arrow_type = ((y < (geom.y + geom.height / 2)) ? GTK_ARROW_DOWN : GTK_ARROW_UP);
- break;
- }
-
- /* set the arrow type of the tray widget */
- xfce_tray_widget_set_arrow_type (XFCE_TRAY_WIDGET (plugin->tray), arrow_type);
-
- /* update the manager orientation */
- xfce_tray_manager_set_orientation (plugin->manager, xfce_screen_position_get_orientation (position));
-}
-
-
-
-static void
-xfce_tray_plugin_icon_added (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayPlugin *plugin)
-{
- gchar *name;
-
- /* get the application name */
- name = xfce_tray_manager_get_application_name (icon);
-
- /* add the icon to the widget */
- xfce_tray_widget_add_with_name (XFCE_TRAY_WIDGET (plugin->tray), icon, name);
-
- /* cleanup */
- g_free (name);
-
- /* show icon */
- gtk_widget_show (icon);
-}
-
-
-
-static void
-xfce_tray_plugin_icon_removed (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayPlugin *plugin)
-{
- /* remove from the tray */
- gtk_container_remove (GTK_CONTAINER (plugin->tray), icon);
-}
-
-
-
-static void
-xfce_tray_plugin_lost_selection (XfceTrayManager *manager,
- XfceTrayPlugin *plugin)
-{
- GdkScreen *screen;
-
- /* get screen */
- screen = gtk_widget_get_screen (GTK_WIDGET (plugin->panel_plugin));
-
- /* message */
- xfce_tray_plugin_message (GTK_MESSAGE_WARNING, screen, _("The tray manager lost selection"));
-}
-
-
-
-static XfceTrayPlugin *
-xfce_tray_plugin_new (XfcePanelPlugin *panel_plugin)
-{
- XfceTrayPlugin *plugin;
- gboolean result;
- GError *error = NULL;
- GdkScreen *screen;
-
- /* create structure */
- plugin = g_slice_new0 (XfceTrayPlugin);
-
- /* set some data */
- plugin->panel_plugin = panel_plugin;
- plugin->manager = NULL;
- plugin->show_frame = TRUE;
-
- /* create the frame */
- plugin->frame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->frame);
- gtk_widget_show (plugin->frame);
-
- /* create tray widget */
- plugin->tray = xfce_tray_widget_new ();
- gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->tray);
- gtk_widget_show (plugin->tray);
-
- /* create a tray manager */
- plugin->manager = xfce_tray_manager_new ();
-
- /* read the plugin settings */
- xfce_tray_plugin_read (plugin);
-
- /* set frame shadow */
- gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), plugin->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
-
- /* get screen */
- screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
-
- /* register the tray */
- result = xfce_tray_manager_register (plugin->manager, screen, &error);
-
- /* check for problems */
- if (G_LIKELY (result == TRUE))
- {
- /* connect signals */
- g_signal_connect (G_OBJECT (plugin->manager), "tray-icon-added", G_CALLBACK (xfce_tray_plugin_icon_added), plugin);
- g_signal_connect (G_OBJECT (plugin->manager), "tray-icon-removed", G_CALLBACK (xfce_tray_plugin_icon_removed), plugin);
- g_signal_connect (G_OBJECT (plugin->manager), "tray-lost-selection", G_CALLBACK (xfce_tray_plugin_lost_selection), plugin);
-
- /* update the plugin position */
- xfce_tray_plugin_update_position (plugin);
- }
- else
- {
- /* show error */
- xfce_tray_plugin_message (GTK_MESSAGE_ERROR, screen, error->message);
-
- /* free error */
- g_error_free (error);
- }
-
- return plugin;
-}
-
-
-
-static void
-xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
- XfceScreenPosition position)
-{
- /* update the plugin position */
- xfce_tray_plugin_update_position (plugin);
-}
-
-
-
-static void
-xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
- GtkOrientation orientation)
-{
- /* update the plugin position */
- xfce_tray_plugin_update_position (plugin);
-}
-
-
-
-static gboolean
-xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
- guint size)
-{
- /* set the border sizes */
- gtk_container_set_border_width (GTK_CONTAINER (plugin->frame), (size > SMALL_PANEL_SIZE && plugin->show_frame) ? 1 : 0);
- gtk_container_set_border_width (GTK_CONTAINER (plugin->tray), plugin->show_frame ? 1 : 0);
-
- /* we handled the size of the plugin */
- return TRUE;
-}
-
-
-
-static void
-xfce_tray_plugin_read (XfceTrayPlugin *plugin)
-{
- gchar *file;
- gchar **names;
- 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);
-
- /* set number of rows */
- xfce_tray_widget_set_rows (XFCE_TRAY_WIDGET (plugin->tray), xfce_rc_read_int_entry (rc, "Rows", 1));
-
- if (G_LIKELY (plugin->manager))
- {
- /* list of known applications */
- names = xfce_rc_get_entries (rc, "Applications");
-
- if (G_LIKELY (names))
- {
- /* set the group */
- xfce_rc_set_group (rc, "Applications");
-
- /* read their visibility */
- for (i = 0; names[i] != NULL; i++)
- {
- /* whether the application is hidden */
- hidden = xfce_rc_read_bool_entry (rc, names[i], FALSE);
-
- /* add the application name */
- xfce_tray_widget_name_add (XFCE_TRAY_WIDGET (plugin->tray), names[i], hidden);
- }
-
- /* cleanup */
- g_strfreev (names);
- }
- }
-
- /* close the rc file */
- xfce_rc_close (rc);
- }
- }
-}
-
-
-
-static void
-xfce_tray_plugin_write (XfceTrayPlugin *plugin)
-{
- gchar *file;
- GList *names, *li;
- XfceRc *rc;
- const gchar *name;
- gboolean hidden;
-
- /* 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);
- xfce_rc_write_int_entry (rc, "Rows", xfce_tray_widget_get_rows (XFCE_TRAY_WIDGET (plugin->tray)));
-
- if (G_LIKELY (plugin->manager))
- {
- /* get the list of known applications */
- names = xfce_tray_widget_name_list (XFCE_TRAY_WIDGET (plugin->tray));
-
- if (names == NULL)
- {
- /* delete group */
- if (xfce_rc_has_group (rc, "Applications"))
- xfce_rc_delete_group (rc, "Applications", FALSE);
- }
- else
- {
- /* save the list of known applications and their visibility */
- xfce_rc_set_group (rc, "Applications");
-
- /* save their state */
- for (li = names; li != NULL; li = li->next)
- {
- /* get name and status */
- name = li->data;
- hidden = xfce_tray_widget_name_hidden (XFCE_TRAY_WIDGET (plugin->tray), name);
-
- /* write entry */
- xfce_rc_write_bool_entry (rc, name, hidden);
- }
-
- /* cleanup */
- g_list_free (names);
- }
- }
-
- /* close the rc file */
- xfce_rc_close (rc);
- }
- }
-}
-
-
-
-static void
-xfce_tray_plugin_free (XfceTrayPlugin *plugin)
-{
- /* unregister manager */
- xfce_tray_manager_unregister (plugin->manager);
-
- /* release */
- g_object_unref (G_OBJECT (plugin->manager));
-
- /* free slice */
- g_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);
-}
diff --git a/plugins/systray/xfce-tray-plugin.h b/plugins/systray/xfce-tray-plugin.h
deleted file mode 100644
index 7be35f4..0000000
--- a/plugins/systray/xfce-tray-plugin.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2007-2009 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__ */
diff --git a/plugins/systray/xfce-tray-widget.c b/plugins/systray/xfce-tray-widget.c
deleted file mode 100644
index 7ebb8d5..0000000
--- a/plugins/systray/xfce-tray-widget.c
+++ /dev/null
@@ -1,847 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2007-2009 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/libxfce4panel.h>
-#include <libxfce4util/libxfce4util.h>
-
-#include "xfce-tray-manager.h"
-#include "xfce-tray-widget.h"
-#include "xfce-tray-plugin.h"
-
-#define XFCE_TRAY_WIDGET_BUTTON_SIZE (16)
-#define XFCE_TRAY_WIDGET_OFFSCREEN (-9999)
-#define XFCE_TRAY_WIDGET_IS_HORIZONTAL(tray) ((tray)->arrow_type == GTK_ARROW_LEFT || (tray)->arrow_type == GTK_ARROW_RIGHT)
-#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_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_add (GtkContainer *container,
- GtkWidget *child);
-static void xfce_tray_widget_remove (GtkContainer *container,
- GtkWidget *child);
-static void xfce_tray_widget_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static GType xfce_tray_widget_child_type (GtkContainer *container);
-static void xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray);
-static gboolean xfce_tray_widget_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- GtkWidget *tray);
-static void xfce_tray_widget_button_clicked (GtkToggleButton *button,
- XfceTrayWidget *tray);
-
-
-
-struct _XfceTrayWidgetClass
-{
- GtkContainerClass __parent__;
-};
-
-struct _XfceTrayWidget
-{
- GtkContainer __parent__;
-
- /* all the icons packed in this box */
- GSList *childeren;
-
- /* table with names, value contains an uint
- * that represents the hidden bool */
- GHashTable *names;
-
- /* expand button */
- GtkWidget *button;
-
- /* position of the arrow button */
- GtkArrowType arrow_type;
-
- /* hidden childeren counter */
- gint n_hidden_childeren;
-
- /* whether hidden icons are visible */
- guint show_hidden : 1;
-
- /* number of rows */
- gint rows;
-};
-
-struct _XfceTrayWidgetChild
-{
- /* the child widget */
- GtkWidget *widget;
-
- /* whether it could be hidden */
- guint hidden : 1;
-
- /* whether the icon is invisible */
- guint invisible : 1;
-
- /* the name of the applcation */
- gchar *name;
-};
-
-
-
-G_DEFINE_TYPE (XfceTrayWidget, xfce_tray_widget, GTK_TYPE_CONTAINER)
-
-
-
-static void
-xfce_tray_widget_class_init (XfceTrayWidgetClass *klass)
-{
- GObjectClass *gobject_class;
- GtkWidgetClass *gtkwidget_class;
- GtkContainerClass *gtkcontainer_class;
-
- 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;
-
- gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
- gtkcontainer_class->add = xfce_tray_widget_add;
- gtkcontainer_class->remove = xfce_tray_widget_remove;
- gtkcontainer_class->forall = xfce_tray_widget_forall;
- gtkcontainer_class->child_type = xfce_tray_widget_child_type;
-}
-
-
-
-static void
-xfce_tray_widget_init (XfceTrayWidget *tray)
-{
- /* initialize the widget */
- GTK_WIDGET_SET_FLAGS (tray, GTK_NO_WINDOW);
- gtk_widget_set_redraw_on_allocate (GTK_WIDGET (tray), FALSE);
-
- /* initialize */
- tray->childeren = NULL;
- tray->button = NULL;
- tray->rows = 1;
- tray->n_hidden_childeren = 0;
- tray->arrow_type = GTK_ARROW_LEFT;
- tray->show_hidden = FALSE;
-
- /* create hash table */
- tray->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
- /* create tray button */
- tray->button = xfce_arrow_button_new (tray->arrow_type);
- 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);
- g_signal_connect (G_OBJECT (tray->button), "button-press-event", G_CALLBACK (xfce_tray_widget_button_press_event), tray);
- gtk_widget_set_parent (tray->button, GTK_WIDGET (tray));
-}
-
-
-
-static void
-xfce_tray_widget_finalize (GObject *object)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (object);
-
- /* check if we're leaking */
- if (G_UNLIKELY (tray->childeren != NULL))
- {
- g_message ("Leaking memory: Not all icons have been removed");
-
- /* free the child list */
- g_slist_free (tray->childeren);
- }
-
- /* destroy the hash table */
- g_hash_table_destroy (tray->names);
-
- 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);
- GSList *li;
- XfceTrayWidgetChild *child_info;
- gint n_columns;
- gint child_size = -1;
- GtkRequisition child_requisition;
- gint n_visible_childeren = 0;
-
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (widget));
- panel_return_if_fail (requisition != NULL);
-
- /* check if we need to hide or show any childeren */
- for (li = tray->childeren; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- /* get the icons size request */
- gtk_widget_size_request (child_info->widget, &child_requisition);
-
- if (G_UNLIKELY (child_requisition.width == 1 || child_requisition.height == 1))
- {
- /* don't do anything with already invisible icons */
- if (child_info->invisible == FALSE)
- {
- /* this icon should not be visible */
- child_info->invisible = TRUE;
-
- /* decrease the hidden counter if needed */
- if (child_info->hidden)
- tray->n_hidden_childeren--;
- }
- }
- else
- {
- /* restore icon if it was previously invisible */
- if (G_UNLIKELY (child_info->invisible))
- {
- /* visible icon */
- child_info->invisible = FALSE;
-
- /* update counter */
- if (child_info->hidden)
- tray->n_hidden_childeren++;
- }
-
- /* count the number of visible childeren */
- if (child_info->hidden == FALSE || tray->show_hidden == TRUE)
- {
- /* pick largest icon */
- if (child_size == -1)
- child_size = MAX (child_requisition.width, child_requisition.height);
- else
- child_size = MAX (child_size, MAX (child_requisition.width, child_requisition.height));
-
- /* increase number of visible childeren */
- n_visible_childeren++;
- }
- }
- }
-
- /* number of columns */
- n_columns = n_visible_childeren / tray->rows;
- if (n_visible_childeren > (n_columns * tray->rows))
- n_columns++;
-
- /* set the width and height needed for the icons */
- if (n_visible_childeren > 0)
- {
- requisition->width = ((child_size + XFCE_TRAY_WIDGET_SPACING) * n_columns) - XFCE_TRAY_WIDGET_SPACING;
- requisition->height = ((child_size + XFCE_TRAY_WIDGET_SPACING) * tray->rows) - XFCE_TRAY_WIDGET_SPACING;
- }
- else
- {
- requisition->width = requisition->height = 0;
- }
-
- /* add the button size if there are hidden icons */
- if (tray->n_hidden_childeren > 0)
- {
- /* add the button size */
- requisition->width += XFCE_TRAY_WIDGET_BUTTON_SIZE;
-
- /* add space */
- if (n_visible_childeren > 0)
- requisition->width += XFCE_TRAY_WIDGET_SPACING;
- }
-
- /* swap the sizes if the orientation is vertical */
- if (!XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- XFCE_TRAY_WIDGET_SWAP_INT (requisition->width, requisition->height);
-
- /* add container border */
- requisition->width += GTK_CONTAINER (widget)->border_width * 2;
- requisition->height += GTK_CONTAINER (widget)->border_width * 2;
-}
-
-
-
-static void
-xfce_tray_widget_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
- XfceTrayWidgetChild *child_info;
- GSList *li;
- gint n;
- gint x, y;
- gint width, height;
- gint offset = 0;
- gint child_size;
- GtkAllocation child_allocation;
-
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (widget));
- panel_return_if_fail (allocation != NULL);
-
- /* set widget allocation */
- widget->allocation = *allocation;
-
- /* get root coordinates */
- x = allocation->x + GTK_CONTAINER (widget)->border_width;
- y = allocation->y + GTK_CONTAINER (widget)->border_width;
-
- /* get real size */
- width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width;
- height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width;
-
- /* child size */
- child_size = XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray) ? height : width;
- child_size -= XFCE_TRAY_WIDGET_SPACING * (tray->rows - 1);
- child_size /= tray->rows;
-
- /* don't allocate a zero width icon */
- if (child_size < 1)
- child_size = 1;
-
- /* position arrow button */
- if (tray->n_hidden_childeren > 0)
- {
- /* initialize allocation */
- child_allocation.x = x;
- child_allocation.y = y;
-
- /* set the width and height */
- if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- {
- child_allocation.width = XFCE_TRAY_WIDGET_BUTTON_SIZE;
- child_allocation.height = height;
- }
- else
- {
- child_allocation.width = width;
- child_allocation.height = XFCE_TRAY_WIDGET_BUTTON_SIZE;
- }
-
- /* position the button on the other side of the tray */
- if (tray->arrow_type == GTK_ARROW_RIGHT)
- child_allocation.x += width - child_allocation.width;
- else if (tray->arrow_type == GTK_ARROW_DOWN)
- child_allocation.y += height - child_allocation.height;
-
- /* set the offset for the icons */
- offset = XFCE_TRAY_WIDGET_BUTTON_SIZE + XFCE_TRAY_WIDGET_SPACING;
-
- /* position the arrow button */
- gtk_widget_size_allocate (tray->button, &child_allocation);
-
- /* show button if not already visible */
- if (!GTK_WIDGET_VISIBLE (tray->button))
- gtk_widget_show (tray->button);
- }
- else if (GTK_WIDGET_VISIBLE (tray->button))
- {
- /* hide the button */
- gtk_widget_hide (tray->button);
- }
-
- /* position icons */
- for (li = tray->childeren, n = 0; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- if (child_info->invisible || (child_info->hidden && !tray->show_hidden))
- {
- /* put icons offscreen */
- child_allocation.x = child_allocation.y = XFCE_TRAY_WIDGET_OFFSCREEN;
- }
- else
- {
- /* set coordinates */
- child_allocation.x = (child_size + XFCE_TRAY_WIDGET_SPACING) * (n / tray->rows) + offset;
- child_allocation.y = (child_size + XFCE_TRAY_WIDGET_SPACING) * (n % tray->rows);
-
- /* increase item 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_type == GTK_ARROW_RIGHT)
- child_allocation.x = width - child_allocation.x - child_size;
- else if (tray->arrow_type == GTK_ARROW_DOWN)
- child_allocation.y = height - child_allocation.y - child_size;
-
- /* add root */
- child_allocation.x += x;
- child_allocation.y += y;
- }
-
- /* set child width and height */
- child_allocation.width = child_size;
- child_allocation.height = child_size;
-
- /* allocate widget size */
- gtk_widget_size_allocate (child_info->widget, &child_allocation);
- }
-}
-
-
-
-static void
-xfce_tray_widget_add (GtkContainer *container,
- GtkWidget *child)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
-
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (container));
-
- /* add the entry */
- xfce_tray_widget_add_with_name (tray, child, NULL);
-}
-
-
-
-static void
-xfce_tray_widget_remove (GtkContainer *container,
- GtkWidget *child)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
- XfceTrayWidgetChild *child_info;
- gboolean need_resize;
- GSList *li;
-
- /* search the child */
- for (li = tray->childeren; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- if (child_info->widget == child)
- {
- /* whether the need to redraw afterwards */
- need_resize = !child_info->hidden;
-
- /* update hidden counter */
- if (child_info->hidden && !child_info->invisible)
- tray->n_hidden_childeren--;
-
- /* remove from list */
- tray->childeren = g_slist_remove_link (tray->childeren, li);
-
- /* free name */
- g_free (child_info->name);
-
- /* free child info */
- g_slice_free (XfceTrayWidgetChild, child_info);
-
- /* unparent the widget */
- gtk_widget_unparent (child);
-
- /* resize when the child was visible */
- if (need_resize)
- gtk_widget_queue_resize (GTK_WIDGET (container));
-
- break;
- }
- }
-}
-
-
-
-static void
-xfce_tray_widget_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
- XfceTrayWidgetChild *child_info;
- GSList *li;
-
- /* for button */
- (*callback) (GTK_WIDGET (tray->button), callback_data);
-
- /* run callback for all childeren */
- for (li = tray->childeren; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- (*callback) (GTK_WIDGET (child_info->widget), callback_data);
- }
-}
-
-
-
-static GType
-xfce_tray_widget_child_type (GtkContainer *container)
-
-{
- return GTK_TYPE_WIDGET;
-}
-
-
-
-static void
-xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray)
-{
- GtkArrowType arrow_type;
-
- /* set arrow type */
- arrow_type = tray->arrow_type;
-
- /* invert the arrow direction when the button is toggled */
- if (tray->show_hidden)
- {
- 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 gboolean
-xfce_tray_widget_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- GtkWidget *tray)
-{
- /* send the event to the tray for the panel menu */
- gtk_widget_event (tray, (GdkEvent *) event);
-
- return FALSE;
-}
-
-
-
-static void
-xfce_tray_widget_button_clicked (GtkToggleButton *button,
- XfceTrayWidget *tray)
-{
- /* whether to show hidden icons */
- tray->show_hidden = gtk_toggle_button_get_active (button);
-
- /* update the arrow */
- xfce_tray_widget_button_set_arrow (tray);
-
- /* queue a resize */
- gtk_widget_queue_resize (GTK_WIDGET (tray));
-}
-
-
-
-static gint
-xfce_tray_widget_compare_function (gconstpointer a,
- gconstpointer b)
-{
- const XfceTrayWidgetChild *child_a = a;
- const XfceTrayWidgetChild *child_b = b;
-
- /* sort hidden icons before visible ones */
- if (child_a->hidden != child_b->hidden)
- return (child_a->hidden ? -1 : 1);
-
- /* put icons without name after the hidden icons */
- if (G_UNLIKELY (child_a->name == NULL || child_b->name == NULL))
- return (child_a->name == child_b->name ? 0 : (child_a->name == NULL ? -1 : 1));
-
- /* sort by name */
- return strcmp (child_a->name, child_b->name);
-}
-
-
-
-GtkWidget *
-xfce_tray_widget_new (void)
-{
- return g_object_new (XFCE_TYPE_TRAY_WIDGET, NULL);
-}
-
-
-
-void
-xfce_tray_widget_add_with_name (XfceTrayWidget *tray,
- GtkWidget *child,
- const gchar *name)
-{
- XfceTrayWidgetChild *child_info;
-
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- panel_return_if_fail (GTK_IS_WIDGET (child));
- panel_return_if_fail (child->parent == NULL);
- panel_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
-
- /* create child info */
- child_info = g_slice_new (XfceTrayWidgetChild);
- child_info->widget = child;
- child_info->invisible = FALSE;
- child_info->name = g_strdup (name);
- child_info->hidden = xfce_tray_widget_name_hidden (tray, child_info->name);
-
- /* update hidden counter */
- if (child_info->hidden)
- tray->n_hidden_childeren++;
-
- /* insert sorted */
- tray->childeren = g_slist_insert_sorted (tray->childeren, child_info, xfce_tray_widget_compare_function);
-
- /* set parent widget */
- gtk_widget_set_parent (child, GTK_WIDGET (tray));
-}
-
-
-
-void
-xfce_tray_widget_set_arrow_type (XfceTrayWidget *tray,
- GtkArrowType arrow_type)
-{
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
-
- if (G_LIKELY (arrow_type != tray->arrow_type))
- {
- /* set new setting */
- tray->arrow_type = arrow_type;
-
- /* update button arrow */
- xfce_tray_widget_button_set_arrow (tray);
-
- /* queue a resize */
- if (tray->childeren != NULL)
- gtk_widget_queue_resize (GTK_WIDGET (tray));
- }
-}
-
-
-
-GtkArrowType
-xfce_tray_widget_get_arrow_type (XfceTrayWidget *tray)
-{
- panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), GTK_ARROW_LEFT);
-
- return tray->arrow_type;
-}
-
-
-
-void
-xfce_tray_widget_set_rows (XfceTrayWidget *tray,
- gint rows)
-{
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
-
- if (G_LIKELY (rows != tray->rows))
- {
- /* set new setting */
- tray->rows = MAX (1, rows);
-
- /* queue a resize */
- if (tray->childeren != NULL)
- gtk_widget_queue_resize (GTK_WIDGET (tray));
- }
-}
-
-
-
-gint
-xfce_tray_widget_get_rows (XfceTrayWidget *tray)
-{
- panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), 1);
-
- return tray->rows;
-}
-
-
-
-void
-xfce_tray_widget_name_add (XfceTrayWidget *tray,
- const gchar *name,
- gboolean hidden)
-{
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- panel_return_if_fail (name != NULL && *name != '\0');
-
- /* insert the application */
- g_hash_table_insert (tray->names, g_strdup (name), GUINT_TO_POINTER (hidden ? 1 : 0));
-}
-
-
-
-void
-xfce_tray_widget_name_update (XfceTrayWidget *tray,
- const gchar *name,
- gboolean hidden)
-{
- XfceTrayWidgetChild *child_info;
- GSList *li;
- gint n_hidden_childeren;
-
- panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- panel_return_if_fail (name != NULL && *name != '\0');
-
- /* replace the old name */
- g_hash_table_replace (tray->names, g_strdup (name), GUINT_TO_POINTER (hidden ? 1 : 0));
-
- /* reset counter */
- n_hidden_childeren = 0;
-
- /* update the icons */
- for (li = tray->childeren; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- /* update the hidden state */
- child_info->hidden = xfce_tray_widget_name_hidden (tray, child_info->name);
-
- /* increase counter if needed */
- if (child_info->hidden && !child_info->invisible)
- n_hidden_childeren++;
- }
-
- if (tray->n_hidden_childeren != n_hidden_childeren)
- {
- /* set value */
- tray->n_hidden_childeren = n_hidden_childeren;
-
- /* sort the list again */
- tray->childeren = g_slist_sort (tray->childeren, xfce_tray_widget_compare_function);
-
- /* update the tray */
- gtk_widget_queue_resize (GTK_WIDGET (tray));
- }
-}
-
-
-
-gboolean
-xfce_tray_widget_name_hidden (XfceTrayWidget *tray,
- const gchar *name)
-{
- gpointer p;
-
- /* do not hide icons without name */
- if (G_UNLIKELY (name == NULL))
- return FALSE;
-
- /* lookup the name in the table */
- p = g_hash_table_lookup (tray->names, name);
-
- /* check the pointer */
- if (G_UNLIKELY (p == NULL))
- {
- /* add the name */
- xfce_tray_widget_name_add (tray, name, FALSE);
-
- /* do not hide the icon */
- return FALSE;
- }
- else
- {
- return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE);
- }
-}
-
-
-
-#if !GLIB_CHECK_VERSION (2,14,0)
-static void
-xfce_tray_widget_name_list_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GList **keys = user_data;
-
- *keys = g_list_prepend (*keys, key);
-}
-#endif
-
-
-
-GList *
-xfce_tray_widget_name_list (XfceTrayWidget *tray)
-{
- GList *keys = NULL;
-
-#if !GLIB_CHECK_VERSION (2,14,0)
- g_hash_table_foreach (tray->names, xfce_tray_widget_name_list_foreach, &keys);
-#else
- /* get the hash table keys */
- keys = g_hash_table_get_keys (tray->names);
-#endif
-
- /* sort the list */
- keys = g_list_sort (keys, (GCompareFunc) strcmp);
-
- return keys;
-}
-
-
-
-void
-xfce_tray_widget_clear_name_list (XfceTrayWidget *tray)
-{
- XfceTrayWidgetChild *child_info;
- GSList *li;
- gint n_hidden_childeren = 0;
-
- /* remove all the entries from the list */
- g_hash_table_remove_all (tray->names);
-
- /* remove hidden flags from all childeren */
- for (li = tray->childeren; li != NULL; li = li->next)
- {
- child_info = li->data;
-
- /* update the hidden state */
- if (child_info->hidden)
- {
- n_hidden_childeren++;
-
- child_info->hidden = FALSE;
- }
- }
-
- /* reset */
- tray->n_hidden_childeren = 0;
-
- /* update tray if needed */
- if (n_hidden_childeren > 0)
- {
- /* sort the list again */
- tray->childeren = g_slist_sort (tray->childeren, xfce_tray_widget_compare_function);
-
- /* update the tray */
- gtk_widget_queue_resize (GTK_WIDGET (tray));
- }
-}
-
diff --git a/plugins/systray/xfce-tray-widget.h b/plugins/systray/xfce-tray-widget.h
deleted file mode 100644
index ddd4581..0000000
--- a/plugins/systray/xfce-tray-widget.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2007-2009 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;
-typedef struct _XfceTrayWidgetChild XfceTrayWidgetChild;
-
-#define XFCE_TRAY_WIDGET_SPACING (2)
-
-#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;
-
-GtkWidget *xfce_tray_widget_new (void) G_GNUC_MALLOC;
-
-void xfce_tray_widget_add_with_name (XfceTrayWidget *tray,
- GtkWidget *child,
- const gchar *name);
-
-void xfce_tray_widget_set_arrow_type (XfceTrayWidget *tray,
- GtkArrowType arrow_type);
-
-GtkArrowType xfce_tray_widget_get_arrow_type (XfceTrayWidget *tray);
-
-void xfce_tray_widget_set_rows (XfceTrayWidget *tray,
- gint rows);
-
-gint xfce_tray_widget_get_rows (XfceTrayWidget *tray);
-
-void xfce_tray_widget_name_add (XfceTrayWidget *tray,
- const gchar *name,
- gboolean hidden);
-
-void xfce_tray_widget_name_update (XfceTrayWidget *tray,
- const gchar *name,
- gboolean hidden);
-
-gboolean xfce_tray_widget_name_hidden (XfceTrayWidget *tray,
- const gchar *name);
-
-GList *xfce_tray_widget_name_list (XfceTrayWidget *tray) G_GNUC_MALLOC;
-
-void xfce_tray_widget_clear_name_list (XfceTrayWidget *tray);
-
-#endif /* !__XFCE_TRAY_WIDGET_H__ */
More information about the Xfce4-commits
mailing list