[Xfce4-commits] r26319 - xfce4-panel/trunk/plugins/systray
Nick Schermer
nick at xfce.org
Fri Nov 16 16:32:40 CET 2007
Author: nick
Date: 2007-11-16 15:32:40 +0000 (Fri, 16 Nov 2007)
New Revision: 26319
Modified:
xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h
xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
Log:
* Reorder things here. The widget is now a normal gtk_container
widget. Should fix problems with un-shown icons.
* Users can set the number of lines in the tray.
* Move application name code from the manager to the widget and
use a hash table for faster lookups.
* The plugin now holds the manager instance, this makes more sence.
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c 2007-11-16 15:32:40 UTC (rev 26319)
@@ -1,5 +1,7 @@
/* $Id$ */
/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
@@ -44,7 +46,6 @@
APPLICATION_ICON,
APPLICATION_NAME,
APPLICATION_HIDDEN,
- APPLICATION_DATA,
N_COLUMNS
};
@@ -56,6 +57,8 @@
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);
@@ -112,8 +115,10 @@
GdkPixbuf *icon;
guint i;
gchar *first_occ;
- const gchar *p, *fallback[][2] =
+ const gchar *p;
+ const gchar *fallback[][2] =
{
+ /* application name , fallback icon name */
{ "xfce-mcs-manager", "input-mouse" },
{ "bluetooth-applet", "stock_bluetooth" }
};
@@ -173,14 +178,30 @@
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;
- XfceTrayApplication *application;
- XfceTrayPlugin *plugin;
+ 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));
@@ -188,23 +209,25 @@
/* get the tree iter */
if (G_LIKELY (gtk_tree_model_get_iter_from_string (model, &iter, path)))
{
- /* get the application data */
- gtk_tree_model_get (model, &iter, APPLICATION_DATA, &application, -1);
+ /* get 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 (application && plugin))
+ if (G_LIKELY (name && plugin))
{
/* update the manager */
- xfce_tray_manager_application_update (plugin->manager, application->name, !application->hidden);
+ xfce_tray_widget_name_update (XFCE_TRAY_WIDGET (plugin->tray), name, !hidden);
- /* sort and update the tray widget */
- xfce_tray_widget_sort (XFCE_TRAY_WIDGET (plugin->tray));
-
/* set the new list value */
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, APPLICATION_HIDDEN, application->hidden, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, APPLICATION_HIDDEN, !hidden, -1);
}
+
+ /* cleanup */
+ g_free (name);
}
}
@@ -242,13 +265,15 @@
GtkWidget *dialog, *dialog_vbox;
GtkWidget *frame, *bin, *button;
GtkWidget *scroll, *treeview;
+ GtkWidget *vbox, *label, *hbox, *spin;
GtkListStore *store;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeIter iter;
- XfceTrayApplication *application;
- GSList *applications, *li;
- gchar *name;
+ GList *names, *li;
+ const gchar *name;
+ gchar *camelcase;
+ gboolean hidden;
GtkIconTheme *icon_theme;
GdkPixbuf *pixbuf;
@@ -264,7 +289,8 @@
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, 350);
+ 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);
@@ -273,20 +299,45 @@
/* appearance */
frame = xfce_create_framebox (_("Appearance"), &bin);
gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, FALSE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
+ 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_container_add (GTK_CONTAINER (bin), button);
+ 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_create_framebox (_("Hidden Applications"), &bin);
gtk_box_pack_start (GTK_BOX (dialog_vbox), frame, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_widget_show (frame);
/* scrolled window */
@@ -297,7 +348,7 @@
gtk_widget_show (scroll);
/* create list store */
- store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
+ store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_BOOLEAN);
/* create treeview */
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
@@ -346,30 +397,32 @@
icon_theme = gtk_icon_theme_get_default ();
/* get the sorted list of applications */
- applications = xfce_tray_manager_application_list (plugin->manager, TRUE);
+ names = xfce_tray_widget_name_list (XFCE_TRAY_WIDGET (plugin->tray));
/* add all the application to the list */
- for (li = applications; li != NULL; li = li->next)
+ for (li = names; li != NULL; li = li->next)
{
- application = li->data;
+ name = li->data;
/* create a camel case name of the application */
- name = xfce_tray_dialogs_camel_case (application->name);
+ 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, name,
- APPLICATION_HIDDEN, application->hidden,
- APPLICATION_DATA, application, -1);
+ APPLICATION_NAME, camelcase,
+ APPLICATION_HIDDEN, hidden, -1);
/* cleanup */
- g_free (name);
+ g_free (camelcase);
/* get the application icon */
- pixbuf = xfce_tray_dialogs_icon (icon_theme, application->name);
+ pixbuf = xfce_tray_dialogs_icon (icon_theme, name);
- if (pixbuf)
+ if (G_LIKELY (pixbuf))
{
/* set the icon */
gtk_list_store_set (store, &iter, APPLICATION_ICON, pixbuf, -1);
@@ -379,6 +432,9 @@
}
}
+ /* cleanup */
+ g_list_free (names);
+
/* show the dialog */
gtk_widget_show (dialog);
}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.c
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-dialogs.h
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c 2007-11-16 15:32:40 UTC (rev 26319)
@@ -81,14 +81,6 @@
XClientMessageEvent *xevent);
static gboolean xfce_tray_manager_handle_undock_request (GtkSocket *socket,
gpointer user_data);
-static gint xfce_tray_manager_application_list_compare (gconstpointer a,
- gconstpointer b);
-static void xfce_tray_manager_application_free (XfceTrayApplication *application);
-static XfceTrayApplication *xfce_tray_manager_application_find (XfceTrayManager *manager,
- const gchar *name);
-static void xfce_tray_manager_application_set_socket (XfceTrayManager *manager,
- GtkWidget *socket,
- Window xwindow);
#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
static void xfce_tray_message_free (XfceTrayMessage *message);
static void xfce_tray_message_remove_from_list (XfceTrayManager *manager,
@@ -98,7 +90,6 @@
enum
{
- TRAY_ICON_SET_PARENT,
TRAY_ICON_ADDED,
TRAY_ICON_REMOVED,
#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
@@ -137,11 +128,9 @@
/* _net_system_tray_s%d atom */
GdkAtom selection_atom;
-
- /* list of known and hidden applications */
- GSList *applications;
};
+#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
struct _XfceTrayMessage
{
/* message string */
@@ -158,6 +147,7 @@
glong remaining_length;
glong timeout;
};
+#endif
@@ -198,15 +188,6 @@
gobject_class = (GObjectClass *)klass;
gobject_class->finalize = xfce_tray_manager_finalize;
- xfce_tray_manager_signals[TRAY_ICON_SET_PARENT] =
- g_signal_new (I_("tray-icon-set-parent"),
- 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_ADDED] =
g_signal_new (I_("tray-icon-added"),
G_OBJECT_CLASS_TYPE (klass),
@@ -266,7 +247,6 @@
/* initialize */
manager->invisible = NULL;
manager->orientation = GTK_ORIENTATION_HORIZONTAL;
- manager->applications = NULL;
#if XFCE_TRAY_MANAGER_ENABLE_MESSAGES
manager->messages = NULL;
#endif
@@ -297,9 +277,6 @@
{
XfceTrayManager *manager = XFCE_TRAY_MANAGER (object);
- /* unregsiter the manager */
- xfce_tray_manager_unregister (manager);
-
/* destroy the hash table */
g_hash_table_destroy (manager->sockets);
@@ -314,19 +291,11 @@
}
#endif
- if (manager->applications)
- {
- /* free all items */
- g_slist_foreach (manager->applications, (GFunc) xfce_tray_manager_application_free, NULL);
-
- /* free the list */
- g_slist_free (manager->applications);
- }
-
G_OBJECT_CLASS (xfce_tray_manager_parent_class)->finalize (object);
}
+
XfceTrayManager *
xfce_tray_manager_new (void)
{
@@ -334,6 +303,7 @@
}
+
gboolean
xfce_tray_manager_check_running (GdkScreen *screen)
{
@@ -471,8 +441,14 @@
gpointer value,
gpointer user_data)
{
- /* undock the socket */
- xfce_tray_manager_handle_undock_request (value, 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);
}
@@ -719,27 +695,6 @@
static void
-xfce_tray_manager_handle_plug_added (GtkSocket *socket,
- XfceTrayManager *manager)
-{
- /* this function works the same as gtk_widget_show_now, but waits
- * until the remote window is mapped. this is needed to fix problems
- * with empty icons in the tray when they are added. */
-
- /* show the socket */
- gtk_widget_show (GTK_WIDGET (socket));
-
- /* enter the main loop until the socket is mapped */
- while (GTK_SOCKET (socket)->is_mapped == FALSE)
- gtk_main_iteration ();
-
- /* add the icon to the tray */
- g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_ADDED], 0, socket);
-}
-
-
-
-static void
xfce_tray_manager_handle_dock_request (XfceTrayManager *manager,
XClientMessageEvent *xevent)
{
@@ -764,18 +719,14 @@
/* connect the xwindow data to the socket */
g_object_set_data_full (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"), xwindow, g_free);
- /* set the application on the socket */
- xfce_tray_manager_application_set_socket (manager, socket, *xwindow);
+ /* add the icon to the tray */
+ g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_ADDED], 0, socket);
- /* set the parent of the icon */
- g_signal_emit (manager, xfce_tray_manager_signals[TRAY_ICON_SET_PARENT], 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-added", G_CALLBACK (xfce_tray_manager_handle_plug_added), manager);
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 */
@@ -786,6 +737,9 @@
}
else
{
+ /* warning */
+ g_warning ("No parent window set, destroying socket");
+
/* not attached successfully, destroy it */
gtk_widget_destroy (socket);
}
@@ -813,7 +767,6 @@
/* unset object data */
g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"), NULL);
- g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-application"), NULL);
/* destroy the socket */
return FALSE;
@@ -869,210 +822,53 @@
-/**
- * known tray applications
- **/
-XfceTrayApplication *
-xfce_tray_manager_application_add (XfceTrayManager *manager,
- const gchar *name,
- gboolean hidden)
+gchar *
+xfce_tray_manager_get_application_name (GtkWidget *socket)
{
- XfceTrayApplication *application;
+ gchar *name = NULL;
+ GdkDisplay *display;
+ gint succeed;
+ XTextProperty xprop;
+ Window *xwindow;
- _panel_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), NULL);
- _panel_return_val_if_fail (name, NULL);
+ /* get the xwindow */
+ xwindow = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-xwindow"));
- /* create structure */
- application = panel_slice_new0 (XfceTrayApplication);
-
- /* set values */
- application->name = g_strdup (name);
- application->hidden = hidden;
-
- /* add to the list */
- manager->applications = g_slist_prepend (manager->applications, application);
-
- /* return the pointer */
- return application;
-}
-
-
-
-void
-xfce_tray_manager_application_update (XfceTrayManager *manager,
- const gchar *name,
- gboolean hidden)
-{
- GSList *li;
- XfceTrayApplication *application;
-
- _panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- _panel_return_if_fail (name);
-
- /* walk through the known window names */
- for (li = manager->applications; li != NULL; li = li->next)
+ if (G_LIKELY (xwindow))
{
- application = li->data;
+ /* get the display of the socket */
+ display = gtk_widget_get_display (socket);
- /* check if the names match */
- if (strcmp (application->name, name) == 0)
- {
- /* set the new hidden state */
- application->hidden = hidden;
+ /* avoid exiting the application on X errors */
+ gdk_error_trap_push ();
- /* stop searching */
- break;
- }
- }
-}
+ /* try to get the wm name (this is more relaiable with qt applications) */
+ succeed = XGetWMName (GDK_DISPLAY_XDISPLAY (display), *xwindow, &xprop);
-
-
-static gint
-xfce_tray_manager_application_list_compare (gconstpointer a,
- gconstpointer b)
-{
- XfceTrayApplication *app_a = (XfceTrayApplication *)a;
- XfceTrayApplication *app_b = (XfceTrayApplication *)b;
-
- /* sort order when one of the names is null */
- if (G_UNLIKELY (app_a->name == NULL || app_b->name == NULL))
- return (app_a->name == app_b->name ? 0 : (app_a->name == NULL ? -1 : 1));
-
- return strcmp (app_a->name, app_b->name);
-}
-
-
-
-GSList *
-xfce_tray_manager_application_list (XfceTrayManager *manager,
- gboolean sorted)
-{
- _panel_return_val_if_fail (XFCE_IS_TRAY_MANAGER (manager), NULL);
-
- /* sort the list if requested */
- if (sorted)
- manager->applications = g_slist_sort (manager->applications, xfce_tray_manager_application_list_compare);
-
- /* return the list */
- return manager->applications;
-}
-
-
-
-static void
-xfce_tray_manager_application_free (XfceTrayApplication *application)
-{
- /* free name */
- g_free (application->name);
-
- /* free structure */
- panel_slice_free (XfceTrayApplication, application);
-}
-
-
-
-static XfceTrayApplication *
-xfce_tray_manager_application_find (XfceTrayManager *manager,
- const gchar *name)
-{
- GSList *li;
- XfceTrayApplication *application;
-
- _panel_return_val_if_fail (name, NULL);
-
- /* walk through the known window names */
- for (li = manager->applications; li != NULL; li = li->next)
- {
- application = li->data;
-
- /* find a matching name and return the pointer */
- if (strcmp (application->name, name) == 0)
- return application;
- }
-
- /* no match was found, add the application and return the pointer */
- return xfce_tray_manager_application_add (manager, name, FALSE);
-}
-
-
-
-static void
-xfce_tray_manager_application_set_socket (XfceTrayManager *manager,
- GtkWidget *socket,
- Window xwindow)
-{
- gchar *name;
- GdkDisplay *display;
- gint succeed;
- XTextProperty xprop;
- XfceTrayApplication *application;
-
- /* get the display of the socket */
- display = gtk_widget_get_display (socket);
-
- /* avoid exiting the application on X errors */
- gdk_error_trap_push ();
-
- /* try to get the wm name (this is more relaiable with qt applications) */
- succeed = XGetWMName (GDK_DISPLAY_XDISPLAY (display), xwindow, &xprop);
-
- /* check if everything went fine */
- if (G_LIKELY (gdk_error_trap_pop () == 0 && succeed >= Success))
- {
- /* check the xprop content */
- if (G_LIKELY (xprop.value && xprop.nitems > 0))
+ /* check if everything went fine */
+ if (G_LIKELY (gdk_error_trap_pop () == 0 && succeed >= Success))
{
- /* if the string is utf-8 valid, set the name */
- if (G_LIKELY (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL)))
+ /* check the xprop content */
+ if (G_LIKELY (xprop.value && xprop.nitems > 0))
{
- /* create the application name (lower case) */
- name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
+ /* if the string is utf-8 valid, set the name */
+ if (G_LIKELY (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL)))
+ {
+ /* create the application name (lower case) */
+ name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
+ }
- /* find or create a structure */
- application = xfce_tray_manager_application_find (manager, name);
-
/* cleanup */
- g_free (name);
-
- /* set the object data */
- g_object_set_data (G_OBJECT (socket), I_("xfce-tray-manager-application"), application);
+ XFree (xprop.value);
}
-
- /* cleanup */
- XFree (xprop.value);
}
}
-}
-
-
-const gchar *
-xfce_tray_manager_application_get_name (GtkWidget *socket)
-{
- XfceTrayApplication *application;
-
- /* get the application data */
- application = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-application"));
-
- return (application ? application->name : NULL);
+ return name;
}
-gboolean
-xfce_tray_manager_application_get_hidden (GtkWidget *socket)
-{
- XfceTrayApplication *application;
-
- /* get the application data */
- application = g_object_get_data (G_OBJECT (socket), I_("xfce-tray-manager-application"));
-
- return (application ? application->hidden : FALSE);
-}
-
-
-
/**
* tray messages
**/
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.c
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h 2007-11-16 15:32:40 UTC (rev 26319)
@@ -24,26 +24,21 @@
#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;
-typedef struct _XfceTrayApplication XfceTrayApplication;
+#endif
-struct _XfceTrayApplication
-{
- /* the name of the applications */
- gchar *name;
-
- /* whether it should be hidden */
- guint hidden : 1;
-};
-
enum
{
XFCE_TRAY_MANAGER_ERROR_SELECTION_FAILED
};
-#define XFCE_TRAY_MANAGER_ENABLE_MESSAGES 0
#define XFCE_TYPE_TRAY_MANAGER (xfce_tray_manager_get_type ())
@@ -54,6 +49,8 @@
#define XFCE_TRAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_TRAY_MANAGER, XfceTrayManagerClass))
#define XFCE_TRAY_MANAGER_ERROR (xfce_tray_manager_error_quark())
+
+
GType xfce_tray_manager_get_type (void) G_GNUC_CONST G_GNUC_INTERNAL;
GQuark xfce_tray_manager_error_quark (void) G_GNUC_INTERNAL;
@@ -73,20 +70,7 @@
void xfce_tray_manager_set_orientation (XfceTrayManager *manager,
GtkOrientation orientation) G_GNUC_INTERNAL;
-XfceTrayApplication *xfce_tray_manager_application_add (XfceTrayManager *manager,
- const gchar *name,
- gboolean hidden) G_GNUC_INTERNAL;
+gchar *xfce_tray_manager_get_application_name (GtkWidget *socket) G_GNUC_MALLOC G_GNUC_INTERNAL;
-void xfce_tray_manager_application_update (XfceTrayManager *manager,
- const gchar *name,
- gboolean hidden) G_GNUC_INTERNAL;
-GSList *xfce_tray_manager_application_list (XfceTrayManager *manager,
- gboolean sorted) G_GNUC_MALLOC G_GNUC_INTERNAL;
-
-const gchar *xfce_tray_manager_application_get_name (GtkWidget *socket) G_GNUC_INTERNAL;
-
-gboolean xfce_tray_manager_application_get_hidden (GtkWidget *socket) G_GNUC_INTERNAL;
-
-
#endif /* !__XFCE_TRAY_MANAGER_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-manager.h
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c 2007-11-16 15:32:40 UTC (rev 26319)
@@ -36,15 +36,16 @@
/* prototypes */
+static void xfce_tray_plugin_message (GtkMessageType type,
+ GdkScreen *screen,
+ const gchar *message);
static gboolean xfce_tray_plugin_check (GdkScreen *screen);
-static GtkArrowType xfce_tray_plugin_button_position (XfcePanelPlugin *panel_plugin);
+static 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 void xfce_tray_plugin_tray_size_changed (XfceTrayPlugin *plugin,
- gint size);
static gboolean xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
guint size);
static void xfce_tray_plugin_read (XfceTrayPlugin *plugin);
@@ -59,7 +60,7 @@
-void
+static void
xfce_tray_plugin_message (GtkMessageType type,
GdkScreen *screen,
const gchar *message)
@@ -100,18 +101,19 @@
-static GtkArrowType
-xfce_tray_plugin_button_position (XfcePanelPlugin *panel_plugin)
+static void
+xfce_tray_plugin_update_position (XfceTrayPlugin *plugin)
{
XfceScreenPosition position;
GdkScreen *screen;
GdkRectangle geom;
gint mon, x, y;
+ GtkArrowType arrow_type;
- _panel_return_val_if_fail (GTK_WIDGET_REALIZED (panel_plugin), GTK_ARROW_LEFT);
+ _panel_return_if_fail (GTK_WIDGET_REALIZED (plugin->panel_plugin));
/* get the plugin position */
- position = xfce_panel_plugin_get_screen_position (panel_plugin);
+ position = xfce_panel_plugin_get_screen_position (plugin->panel_plugin);
/* get the button position */
switch (position)
@@ -119,50 +121,111 @@
/* horizontal west */
case XFCE_SCREEN_POSITION_NW_H:
case XFCE_SCREEN_POSITION_SW_H:
- return GTK_ARROW_RIGHT;
+ 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:
- return GTK_ARROW_LEFT;
+ arrow_type = GTK_ARROW_LEFT;
+ break;
/* vertical north */
case XFCE_SCREEN_POSITION_NW_V:
case XFCE_SCREEN_POSITION_NE_V:
- return GTK_ARROW_DOWN;
+ 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:
- return GTK_ARROW_UP;
+ arrow_type = GTK_ARROW_UP;
+ break;
/* floating */
default:
/* get the screen information */
- screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
- mon = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (panel_plugin)->window);
+ 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 (panel_plugin)->window, &x, &y);
+ 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)
- return ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
+ arrow_type = ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
else
- return ((y < (geom.y + geom.height / 2)) ? GTK_ARROW_DOWN : GTK_ARROW_UP);
+ 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;
- GtkArrowType position;
+ gboolean result;
+ GError *error = NULL;
+ GdkScreen *screen;
/* create structure */
plugin = panel_slice_new0 (XfceTrayPlugin);
@@ -172,33 +235,54 @@
plugin->manager = NULL;
plugin->show_frame = TRUE;
- /* try to create the tray */
+ /* 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_set_border_width (GTK_CONTAINER (plugin->tray), 1);
+ gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->tray);
+ gtk_widget_show (plugin->tray);
- /* get the manager */
- plugin->manager = xfce_tray_widget_get_manager (XFCE_TRAY_WIDGET (plugin->tray));
+ /* create a tray manager */
+ plugin->manager = xfce_tray_manager_new ();
- /* set arrow postion */
- position = xfce_tray_plugin_button_position (panel_plugin);
- xfce_tray_widget_set_arrow_position (XFCE_TRAY_WIDGET (plugin->tray), position);
-
/* read the plugin settings */
xfce_tray_plugin_read (plugin);
- /* create the frame */
- plugin->frame = gtk_frame_new (NULL);
+ /* set frame shadow */
gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), plugin->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
- gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->frame);
- gtk_widget_show (plugin->frame);
- /* add the tray */
- gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->tray);
- gtk_widget_show (plugin->tray);
+ /* get screen */
+ screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
- /* connect signal to handle the real plugin size */
- g_signal_connect_swapped (G_OBJECT (plugin->tray), "tray-size-changed",
- G_CALLBACK (xfce_tray_plugin_tray_size_changed), 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;
}
@@ -208,13 +292,8 @@
xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
XfceScreenPosition position)
{
- GtkArrowType button_position;
-
- /* get the new position */
- button_position = xfce_tray_plugin_button_position (plugin->panel_plugin);
-
- /* set the position */
- xfce_tray_widget_set_arrow_position (XFCE_TRAY_WIDGET (plugin->tray), button_position);
+ /* update the plugin position */
+ xfce_tray_plugin_update_position (plugin);
}
@@ -223,33 +302,12 @@
xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
GtkOrientation orientation)
{
- /* invoke the function above */
- xfce_tray_plugin_screen_position_changed (plugin, XFCE_SCREEN_POSITION_NONE);
+ /* update the plugin position */
+ xfce_tray_plugin_update_position (plugin);
}
-static void
-xfce_tray_plugin_tray_size_changed (XfceTrayPlugin *plugin,
- gint size)
-{
- gint panel_size;
-
- /* get the panel size */
- panel_size = xfce_panel_plugin_get_size (plugin->panel_plugin);
-
- /* correct the requested plugin size */
- size += panel_size > SMALL_PANEL_SIZE ? 6 : 4;
-
- /* update the plugin size */
- if (xfce_panel_plugin_get_orientation (plugin->panel_plugin) == GTK_ORIENTATION_HORIZONTAL)
- gtk_widget_set_size_request (GTK_WIDGET (plugin->panel_plugin), size, panel_size);
- else
- gtk_widget_set_size_request (GTK_WIDGET (plugin->panel_plugin), panel_size, size);
-}
-
-
-
static gboolean
xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
guint size)
@@ -262,9 +320,6 @@
/* get the border size */
border = size > SMALL_PANEL_SIZE ? 6 : 4;
- /* set the new plugin size */
- xfce_tray_widget_set_size_request (XFCE_TRAY_WIDGET (plugin->tray), size - border);
-
/* we handled the size of the plugin */
return TRUE;
}
@@ -275,7 +330,7 @@
xfce_tray_plugin_read (XfceTrayPlugin *plugin)
{
gchar *file;
- gchar **applications;
+ gchar **names;
gboolean hidden;
XfceRc *rc;
guint i;
@@ -299,28 +354,31 @@
/* 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 */
- applications = xfce_rc_get_entries (rc, "Applications");
+ names = xfce_rc_get_entries (rc, "Applications");
- if (G_LIKELY (applications))
+ if (G_LIKELY (names))
{
/* set the group */
xfce_rc_set_group (rc, "Applications");
/* read their visibility */
- for (i = 0; applications[i] != NULL; i++)
+ for (i = 0; names[i] != NULL; i++)
{
/* whether the application is hidden */
- hidden = xfce_rc_read_bool_entry (rc, applications[i], FALSE);
+ hidden = xfce_rc_read_bool_entry (rc, names[i], FALSE);
/* add the application name */
- xfce_tray_manager_application_add (plugin->manager, applications[i], hidden);
+ xfce_tray_widget_name_add (XFCE_TRAY_WIDGET (plugin->tray), names[i], hidden);
}
/* cleanup */
- g_strfreev (applications);
+ g_strfreev (names);
}
}
@@ -335,10 +393,11 @@
static void
xfce_tray_plugin_write (XfceTrayPlugin *plugin)
{
- gchar *file;
- GSList *applications, *li;
- XfceRc *rc;
- XfceTrayApplication *application;
+ 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);
@@ -358,6 +417,7 @@
/* 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))
{
@@ -365,16 +425,21 @@
xfce_rc_set_group (rc, "Applications");
/* get the list of known applications */
- applications = xfce_tray_manager_application_list (plugin->manager, FALSE);
+ names = xfce_tray_widget_name_list (XFCE_TRAY_WIDGET (plugin->tray));
/* save their state */
- for (li = applications; li != NULL; li = li->next)
+ for (li = names; li != NULL; li = li->next)
{
- application = li->data;
+ /* get name and status */
+ name = li->data;
+ hidden = xfce_tray_widget_name_hidden (XFCE_TRAY_WIDGET (plugin->tray), name);
- if (G_LIKELY (application->name))
- xfce_rc_write_bool_entry (rc, application->name, application->hidden);
+ /* write entry */
+ xfce_rc_write_bool_entry (rc, name, hidden);
}
+
+ /* cleanup */
+ g_list_free (names);
}
/* close the rc file */
@@ -388,6 +453,12 @@
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 */
panel_slice_free (XfceTrayPlugin, plugin);
}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.c
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h 2007-11-16 15:32:40 UTC (rev 26319)
@@ -38,9 +38,5 @@
guint show_frame : 1;
};
-void xfce_tray_plugin_message (GtkMessageType type,
- GdkScreen *screen,
- const gchar *message);
-
#endif /* !__XFCE_TRAY_PLUGIN_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-plugin.h
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c 2007-11-16 15:32:40 UTC (rev 26319)
@@ -36,15 +36,9 @@
#include "xfce-tray-plugin.h"
#define XFCE_TRAY_WIDGET_BUTTON_SIZE (16)
-#define XFCE_TRAY_WIDGET_REDRAW_DELAY (250)
-#define XFCE_TRAY_WIDGET_SPACING (1)
-#define XFCE_TRAY_WIDGET_LINE_HEIGHT (24 + 2 * XFCE_TRAY_WIDGET_SPACING)
#define XFCE_TRAY_WIDGET_OFFSCREEN (-9999)
-#define XFCE_TRAY_WIDGET_IS_HORIZONTAL(obj) ((obj)->arrow_position == GTK_ARROW_LEFT || (obj)->arrow_position == GTK_ARROW_RIGHT)
-#define XFCE_TRAY_WIDGET_IS_SOUTH_EAST(obj) ((obj)->arrow_position == GTK_ARROW_RIGHT || (obj)->arrow_position == GTK_ARROW_DOWN)
-#define XFCE_TRAY_WIDGET_GET_ORIENTATION(obj) (XFCE_TRAY_WIDGET_IS_HORIZONTAL (obj) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL)
-#define XFCE_TRAY_WIDGET_SWAP_INT(x,y) G_STMT_START{ gint __v = x; x = y; y = __v; }G_STMT_END
-#define XFCE_TRAY_WIDGET_N_LINES(size) (MAX (1, (size) / XFCE_TRAY_WIDGET_LINE_HEIGHT))
+#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
@@ -52,32 +46,25 @@
static void xfce_tray_widget_class_init (XfceTrayWidgetClass *klass);
static void xfce_tray_widget_init (XfceTrayWidget *tray);
static void xfce_tray_widget_finalize (GObject *object);
-static void xfce_tray_widget_style_set (GtkWidget *widget,
- GtkStyle *previous_style);
-static void xfce_tray_widget_map (GtkWidget *widget);
-static void xfce_tray_widget_screen_changed (GtkWidget *widget,
- GdkScreen *previous_screen);
-static gint xfce_tray_widget_expose_event (GtkWidget *widget,
- GdkEventExpose *event);
+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 void xfce_tray_widget_button_clicked (GtkToggleButton *button,
- XfceTrayWidget *tray);
static gboolean xfce_tray_widget_button_press_event (GtkWidget *widget,
GdkEventButton *event,
GtkWidget *tray);
-static gint xfce_tray_widget_compare_function (gconstpointer a,
- gconstpointer b);
-static void xfce_tray_widget_icon_added (XfceTrayManager *manager,
- GtkWidget *icon,
+static void xfce_tray_widget_button_clicked (GtkToggleButton *button,
XfceTrayWidget *tray);
-static void xfce_tray_widget_icon_removed (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayWidget *tray);
-static gint xfce_tray_widget_size_request (XfceTrayWidget *tray,
- gint size);
-static gboolean xfce_tray_widget_redraw_idle (gpointer user_data);
-static void xfce_tray_widget_redraw_destroyed (gpointer user_data);
-static void xfce_tray_widget_redraw (XfceTrayWidget *tray);
@@ -88,41 +75,49 @@
struct _XfceTrayWidget
{
- GtkContainer __parent__;
+ GtkContainer __parent__;
- /* tray manager of this tray */
- XfceTrayManager *manager;
+ /* all the icons packed in this box */
+ GSList *childeren;
- /* arrow toggle button */
- GtkWidget *button;
+ /* table with names, value contains an uint
+ * that represents the hidden bool */
+ GHashTable *names;
- /* all the icons packed in this box */
- GSList *childeren;
+ /* expand button */
+ GtkWidget *button;
- /* counters for the icons in the list */
- guint n_childeren;
- guint n_hidden_childeren;
+ /* position of the arrow button */
+ GtkArrowType arrow_type;
+ /* hidden childeren counter */
+ gint n_hidden_childeren;
+
/* whether hidden icons are visible */
- guint all_visible : 1;
+ guint show_hidden : 1;
- guint idle_redraw_id;
+ /* spacing between the childeren */
+ gint spacing;
- /* properties */
- gint size;
- GtkArrowType arrow_position;
+ /* number of rows */
+ gint rows;
};
-enum
+struct _XfceTrayWidgetChild
{
- TRAY_SIZE_CHANGED,
- LAST_SIGNAL
+ /* the child widget */
+ GtkWidget *widget;
+
+ /* whether it could be hidden */
+ guint hidden : 1;
+
+ /* the name of the applcation */
+ gchar *name;
};
static GObjectClass *xfce_tray_widget_parent_class;
-static guint xfce_tray_widget_signals[LAST_SIGNAL];
@@ -161,23 +156,14 @@
gobject_class->finalize = xfce_tray_widget_finalize;
gtkwidget_class = GTK_WIDGET_CLASS (klass);
- gtkwidget_class->style_set = xfce_tray_widget_style_set;
- gtkwidget_class->expose_event = xfce_tray_widget_expose_event;
- gtkwidget_class->map = xfce_tray_widget_map;
- gtkwidget_class->screen_changed = xfce_tray_widget_screen_changed;
+ 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 = NULL;
- gtkcontainer_class->remove = NULL;
-
- xfce_tray_widget_signals[TRAY_SIZE_CHANGED] =
- g_signal_new (I_("tray-size-changed"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
+ 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;
}
@@ -185,19 +171,29 @@
static void
xfce_tray_widget_init (XfceTrayWidget *tray)
{
- /* for realize */
+ /* 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->manager = NULL;
- tray->n_childeren = 0;
+ tray->spacing = 1;
+ tray->rows = 1;
tray->n_hidden_childeren = 0;
- tray->all_visible = FALSE;
- tray->arrow_position = GTK_ARROW_LEFT;
- tray->size = -1;
- tray->idle_redraw_id = 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));
}
@@ -207,591 +203,603 @@
{
XfceTrayWidget *tray = XFCE_TRAY_WIDGET (object);
- /* stop idle timeout */
- if (tray->idle_redraw_id != 0)
- g_source_remove (tray->idle_redraw_id);
+ /* 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);
+ /* free the child list */
+ g_slist_free (tray->childeren);
+ }
- /* release the manager */
- g_object_unref (G_OBJECT (tray->manager));
+ /* destroy the hash table */
+ g_hash_table_destroy (tray->names);
G_OBJECT_CLASS (xfce_tray_widget_parent_class)->finalize (object);
}
-static gint
-xfce_tray_widget_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
+static void
+xfce_tray_widget_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
- GSList *li;
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+ GSList *li;
+ XfceTrayWidgetChild *child_info;
+ gint child_size = 1;
+ gint n_columns;
+ gint n_visible_childeren = 0;
- /* expose the button, because it doesn't have its own window */
- gtk_container_propagate_expose (GTK_CONTAINER (widget), tray->button, event);
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (widget));
+ _panel_return_if_fail (requisition != NULL);
- /* do a reallocate to the tray icons */
for (li = tray->childeren; li != NULL; li = li->next)
- gtk_widget_size_allocate (li->data, >K_WIDGET (li->data)->allocation);
+ {
+ child_info = li->data;
- return FALSE;
-}
+ /* ship hidden icons if needed */
+ if (child_info->hidden == FALSE || tray->show_hidden == TRUE)
+ {
+ /* we use the child allocation for size request here, this is not entirely legal, but
+ * it seems to work better for tray icons since they request weird sizes sometimes */
+ child_size = MAX (child_size, MAX (child_info->widget->allocation.width,
+ child_info->widget->allocation.height));
+ /* 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++;
-static void
-xfce_tray_widget_style_set (GtkWidget *widget,
- GtkStyle *previous_style)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
- GSList *li;
- GtkStyle *style;
+ /* set the width and height needed for the icons */
+ if (n_visible_childeren > 0)
+ {
+ requisition->width = ((child_size + tray->spacing) * n_columns) - tray->spacing;
+ requisition->height = ((child_size + tray->spacing) * tray->rows) - tray->spacing;
+ }
+ else
+ {
+ requisition->width = requisition->height = 0;
+ }
- /* get the style */
- style = gtk_widget_get_style (widget);
-
- /* style must be attached an widget must be realized */
- if (style && GTK_STYLE_ATTACHED (style) && GTK_WIDGET_REALIZED (widget))
+ /* add the button size if there are hidden icons */
+ if (tray->n_hidden_childeren > 0)
{
- /* set the button style */
- if (tray->button)
- gtk_widget_set_style (tray->button, style);
+ /* add the button size */
+ requisition->width += XFCE_TRAY_WIDGET_BUTTON_SIZE;
- /* send the style to all the childeren */
- for (li = tray->childeren; li != NULL; li = li->next)
- gtk_widget_set_style (GTK_WIDGET (li->data), style);
+ /* add space */
+ if (n_visible_childeren > 0)
+ requisition->width += tray->spacing;
}
- /* invoke the parent */
- GTK_WIDGET_CLASS (xfce_tray_widget_parent_class)->style_set (widget, previous_style);
+ /* 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_map (GtkWidget *widget)
+xfce_tray_widget_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
+ 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;
- /* we've been mapped */
- GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (widget));
+ _panel_return_if_fail (allocation != NULL);
- /* destroy old button on remap (screen changed) */
- if (G_UNLIKELY (tray->button))
- gtk_widget_destroy (tray->button);
+ /* set widget allocation */
+ widget->allocation = *allocation;
- /* create the arrow button (needs a mapped tray before the parent is set) */
- tray->button = xfce_arrow_button_new (tray->arrow_position);
- GTK_WIDGET_UNSET_FLAGS (tray->button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
- gtk_button_set_focus_on_click (GTK_BUTTON (tray->button), FALSE);
- g_signal_connect (G_OBJECT (tray->button), "clicked", G_CALLBACK (xfce_tray_widget_button_clicked), tray);
- 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, widget);
- gtk_widget_show (tray->button);
-}
+ /* 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 -= tray->spacing * (tray->rows - 1);
+ child_size /= tray->rows;
-static void
-xfce_tray_widget_screen_changed (GtkWidget *widget,
- GdkScreen *previous_screen)
-{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (widget);
- gboolean succeed;
- GdkScreen *screen;
- gchar *message;
+ /* position arrow button */
+ if (tray->n_hidden_childeren > 0)
+ {
+ /* initialize allocation */
+ child_allocation.x = x;
+ child_allocation.y = y;
- /* unregister the manager */
- xfce_tray_manager_unregister (tray->manager);
+ /* 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;
+ }
- /* get screen */
- screen = gtk_widget_get_screen (widget);
+ /* 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;
- /* register the manager for this screen */
- succeed = xfce_tray_manager_register (tray->manager, screen, NULL);
+ /* set the offset for the icons */
+ offset = XFCE_TRAY_WIDGET_BUTTON_SIZE + tray->spacing;
- if (G_LIKELY (succeed))
+ /* 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))
{
- /* set the orienation */
- xfce_tray_manager_set_orientation (tray->manager, XFCE_TRAY_WIDGET_GET_ORIENTATION (tray));
+ /* hide the button */
+ gtk_widget_hide (tray->button);
}
- else
+
+ /* position icons */
+ for (li = tray->childeren, n = 0; li != NULL; li = li->next)
{
- /* create message */
- message = g_strdup_printf (_("Failed to register the system tray for screen %d"),
- gdk_screen_get_number (screen));
+ child_info = li->data;
- /* show message */
- xfce_tray_plugin_message (GTK_MESSAGE_ERROR, screen, message);
+ if (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 + tray->spacing) * (n / tray->rows) + offset;
+ child_allocation.y = (child_size + tray->spacing) * (n % tray->rows);
- /* cleanup */
- g_free (message);
- }
-}
+ /* 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;
-static void
-xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray)
-{
- GtkArrowType arrow_type;
+ /* add root */
+ child_allocation.x += x;
+ child_allocation.y += y;
+ }
- /* return when the button has not been mapped */
- if (tray->button == NULL)
- return;
+ /* set child width and height */
+ child_allocation.width = child_size;
+ child_allocation.height = child_size;
- /* get the origional arrow type */
- arrow_type = tray->arrow_position;
-
- /* invert the arrow direction when the button is toggled */
- if (tray->all_visible)
- {
- if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- arrow_type = (arrow_type == GTK_ARROW_LEFT ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
- else
- arrow_type = (arrow_type == GTK_ARROW_UP ? GTK_ARROW_DOWN : GTK_ARROW_UP);
+ /* allocate widget size */
+ gtk_widget_size_allocate (child_info->widget, &child_allocation);
}
-
- /* set the arrow type */
- xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (tray->button), arrow_type);
}
static void
-xfce_tray_widget_button_clicked (GtkToggleButton *button,
- XfceTrayWidget *tray)
+xfce_tray_widget_add (GtkContainer *container,
+ GtkWidget *child)
{
- /* set the new visible state */
- tray->all_visible = gtk_toggle_button_get_active (button);
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
- /* set the button arrow */
- xfce_tray_widget_button_set_arrow (tray);
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (container));
- /* update the tray */
- xfce_tray_widget_redraw (tray);
+ /* add the entry */
+ xfce_tray_widget_add_with_name (tray, child, NULL);
}
-static gboolean
-xfce_tray_widget_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- GtkWidget *tray)
+static void
+xfce_tray_widget_remove (GtkContainer *container,
+ GtkWidget *child)
{
- /* send the event to the tray for the panel menu */
- gtk_widget_event (tray, (GdkEvent *)event);
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
+ XfceTrayWidgetChild *child_info;
+ gboolean need_resize;
+ GSList *li;
- return FALSE;
-}
+ /* 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)
+ tray->n_hidden_childeren--;
-static gint
-xfce_tray_widget_compare_function (gconstpointer a,
- gconstpointer b)
-{
- gboolean a_hidden, b_hidden;
- const gchar *a_wmname, *b_wmname;
+ /* remove from list */
+ tray->childeren = g_slist_remove_link (tray->childeren, li);
- /* get hidden state */
- a_hidden = xfce_tray_manager_application_get_hidden (GTK_WIDGET (a));
- b_hidden = xfce_tray_manager_application_get_hidden (GTK_WIDGET (b));
+ /* free name */
+ g_free (child_info->name);
- /* sort hidden icons before visible ones */
- if (a_hidden != b_hidden)
- return (a_hidden ? -1 : 1);
+ /* free child info */
+ panel_slice_free (XfceTrayWidgetChild, child_info);
- /* get the window names */
- a_wmname = xfce_tray_manager_application_get_name (GTK_WIDGET (a));
- b_wmname = xfce_tray_manager_application_get_name (GTK_WIDGET (b));
+ /* unparent the widget */
+ gtk_widget_unparent (child);
- /* return when one of them has no name */
- if (G_UNLIKELY (!a_wmname || !b_wmname))
- return (a_wmname == b_wmname ? 0 : (!a_wmname ? -1 : 1));
+ /* resize when the child was visible */
+ if (need_resize)
+ gtk_widget_queue_resize (GTK_WIDGET (container));
- return strcmp (a_wmname, b_wmname);
+ break;
+ }
+ }
}
static void
-xfce_tray_widget_icon_set_parent (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayWidget *tray)
+xfce_tray_widget_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
{
- _panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- _panel_return_if_fail (GTK_IS_WIDGET (icon));
+ XfceTrayWidget *tray = XFCE_TRAY_WIDGET (container);
+ XfceTrayWidgetChild *child_info;
+ GSList *li;
- /* set the parent window */
- gtk_widget_set_parent (icon, GTK_WIDGET (tray));
+ /* 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 void
-xfce_tray_widget_icon_added (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayWidget *tray)
+static GType
+xfce_tray_widget_child_type (GtkContainer *container)
+
{
- gboolean hidden;
+ return GTK_TYPE_WIDGET;
+}
- _panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- _panel_return_if_fail (GTK_IS_WIDGET (icon));
- _panel_return_if_fail (GTK_WIDGET_DRAWABLE (tray));
- _panel_return_if_fail (GTK_WIDGET_DRAWABLE (icon));
- /* add the icon to the list */
- tray->childeren = g_slist_insert_sorted (tray->childeren, icon, xfce_tray_widget_compare_function);
- /* increase counter */
- tray->n_childeren++;
+static void
+xfce_tray_widget_button_set_arrow (XfceTrayWidget *tray)
+{
+ GtkArrowType arrow_type;
- /* whether this icon could be hidden */
- hidden = xfce_tray_manager_application_get_hidden (icon);
+ /* set arrow type */
+ arrow_type = tray->arrow_type;
- /* increase hidden counter */
- if (hidden)
- tray->n_hidden_childeren++;
+ /* 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);
+ }
- /* update the tray */
- xfce_tray_widget_redraw (tray);
+ /* set the arrow type */
+ xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (tray->button), arrow_type);
}
-static void
-xfce_tray_widget_icon_removed (XfceTrayManager *manager,
- GtkWidget *icon,
- XfceTrayWidget *tray)
+static gboolean
+xfce_tray_widget_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ GtkWidget *tray)
{
- _panel_return_if_fail (XFCE_IS_TRAY_MANAGER (manager));
- _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- _panel_return_if_fail (GTK_IS_WIDGET (icon));
+ /* send the event to the tray for the panel menu */
+ gtk_widget_event (tray, (GdkEvent *) event);
- /* decrease counter */
- tray->n_childeren--;
+ return FALSE;
+}
- /* remove the child from the list */
- tray->childeren = g_slist_remove (tray->childeren, icon);
- /* handle hidden icons */
- if (xfce_tray_manager_application_get_hidden (icon))
- {
- /* decrease hidden counter */
- tray->n_hidden_childeren--;
- /* collapse the hidden button */
- if (tray->n_hidden_childeren == 0 && tray->button)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tray->button), 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 tray */
- xfce_tray_widget_redraw (tray);
+ /* update the arrow */
+ xfce_tray_widget_button_set_arrow (tray);
+
+ /* queue a resize */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
}
-GtkWidget *
-xfce_tray_widget_new (void)
+static gint
+xfce_tray_widget_compare_function (gconstpointer a,
+ gconstpointer b)
{
- XfceTrayWidget *tray;
+ const XfceTrayWidgetChild *child_a = a;
+ const XfceTrayWidgetChild *child_b = b;
- /* create a tray */
- tray = g_object_new (XFCE_TYPE_TRAY_WIDGET, NULL);
+ /* sort hidden icons before visible ones */
+ if (child_a->hidden != child_b->hidden)
+ return (child_a->hidden ? -1 : 1);
- /* new tray manager */
- tray->manager = xfce_tray_manager_new ();
+ /* 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));
- /* manager signals */
- g_signal_connect (G_OBJECT (tray->manager), "tray-icon-set-parent", G_CALLBACK (xfce_tray_widget_icon_set_parent), tray);
- g_signal_connect (G_OBJECT (tray->manager), "tray-icon-added", G_CALLBACK (xfce_tray_widget_icon_added), tray);
- g_signal_connect (G_OBJECT (tray->manager), "tray-icon-removed", G_CALLBACK (xfce_tray_widget_icon_removed), tray);
- //g_signal_connect (G_OBJECT (tray->manager), "tray-message-sent", G_CALLBACK (xfce_tray_widget_message_sent), tray);
- //g_signal_connect (G_OBJECT (tray->manager), "tray-message-cancelled", G_CALLBACK (xfce_tray_widget_message_cancelled), tray);
- //g_signal_connect (G_OBJECT (tray->manager), "tray-lost-selection", G_CALLBACK (xfce_tray_widget_lost_selection), tray);
-
- return GTK_WIDGET (tray);
+ /* sort by name */
+ return strcmp (child_a->name, child_b->name);
}
-static gint
-xfce_tray_widget_size_request (XfceTrayWidget *tray,
- gint size)
+GtkWidget *
+xfce_tray_widget_new (void)
{
- gint lines, child_size;
- gint n_childeren, columns;
- gint req_size;
+ return g_object_new (XFCE_TYPE_TRAY_WIDGET, NULL);
+}
- /* calculate the number of lines */
- lines = XFCE_TRAY_WIDGET_N_LINES (size);
- /* calculate the requested child size */
- child_size = (size - (XFCE_TRAY_WIDGET_SPACING * (lines - 1))) / lines;
- /* number of icons in the tray */
- n_childeren = tray->n_childeren;
- if (!tray->all_visible)
- n_childeren -= tray->n_hidden_childeren;
+void
+xfce_tray_widget_add_with_name (XfceTrayWidget *tray,
+ GtkWidget *child,
+ const gchar *name)
+{
+ XfceTrayWidgetChild *child_info;
- /* number of columns in the tray */
- columns = n_childeren / lines;
- if (n_childeren > (columns * lines))
- columns++;
+ _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));
- /* calculate the tray size we can set */
- req_size = (child_size * columns) + (XFCE_TRAY_WIDGET_SPACING * MAX (columns - 1, 0));
+ /* create child info */
+ child_info = panel_slice_new (XfceTrayWidgetChild);
+ child_info->widget = child;
+ child_info->name = g_strdup (name);
+ child_info->hidden = xfce_tray_widget_name_hidden (tray, child_info->name);
- /* add the hidden button when visible */
- if (tray->n_hidden_childeren > 0)
- {
- req_size += XFCE_TRAY_WIDGET_BUTTON_SIZE;
+ /* update hidden counter */
+ if (child_info->hidden)
+ tray->n_hidden_childeren++;
- /* space between the button and the icons */
- if (columns > 0)
- req_size += XFCE_TRAY_WIDGET_SPACING;
- }
+ /* insert sorted */
+ tray->childeren = g_slist_insert_sorted (tray->childeren, child_info, xfce_tray_widget_compare_function);
- return req_size;
+ /* set parent widget */
+ gtk_widget_set_parent (child, GTK_WIDGET (tray));
}
-static gboolean
-xfce_tray_widget_redraw_idle (gpointer user_data)
+void
+xfce_tray_widget_set_arrow_type (XfceTrayWidget *tray,
+ GtkArrowType arrow_type)
{
- XfceTrayWidget *tray = XFCE_TRAY_WIDGET (user_data);
- GtkWidget *widget = GTK_WIDGET (user_data);
- gint x, y, width, height;
- GSList *li;
- GtkWidget *child;
- GtkAllocation child_allocation;
- gint n = 0, i = 0;
- gint x_offset = 0;
- gint child_size, lines;
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- GDK_THREADS_ENTER ();
+ if (G_LIKELY (arrow_type != tray->arrow_type))
+ {
+ /* set new setting */
+ tray->arrow_type = arrow_type;
- /* get the root coordinates of this widget */
- x = widget->allocation.x;
- y = widget->allocation.y;
+ /* update button arrow */
+ xfce_tray_widget_button_set_arrow (tray);
- /* guess the coordinates when the widget is not allocated yet */
- if (G_UNLIKELY (x == -1 || y == -1))
- x = y = tray->size < 22 ? 2 : 3;
+ /* queue a resize */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
+ }
+}
- /* calculate the requested size */
- height = width = xfce_tray_widget_size_request (tray, tray->size);
- /* send this to the panel */
- g_signal_emit (tray, xfce_tray_widget_signals[TRAY_SIZE_CHANGED], 0, width);
- /* set the fixed size */
- if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- height = tray->size;
- else
- width = tray->size;
+GtkArrowType
+xfce_tray_widget_get_arrow_type (XfceTrayWidget *tray)
+{
+ _panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), GTK_ARROW_LEFT);
- /* calculate the number of lines */
- lines = XFCE_TRAY_WIDGET_N_LINES (tray->size);
+ return tray->arrow_type;
+}
- /* calculate the icon width and height */
- child_size = (tray->size - (XFCE_TRAY_WIDGET_SPACING * (lines - 1))) / lines;
- /* allocation for the arrow button */
- if (tray->n_hidden_childeren > 0)
- {
- /* set the coordinates and default size */
- child_allocation.x = x;
- child_allocation.y = y;
- child_allocation.width = child_allocation.height = XFCE_TRAY_WIDGET_BUTTON_SIZE;
- /* set the offset for the icons */
- x_offset = XFCE_TRAY_WIDGET_BUTTON_SIZE + XFCE_TRAY_WIDGET_SPACING;
+void
+xfce_tray_widget_set_spacing (XfceTrayWidget *tray,
+ gint spacing)
+{
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- /* position the button on the other side of the tray */
- if (XFCE_TRAY_WIDGET_IS_SOUTH_EAST (tray))
- {
- /* set the coordinates to the other side of the tray */
- if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- child_allocation.x += width - XFCE_TRAY_WIDGET_BUTTON_SIZE;
- else
- child_allocation.y += height - XFCE_TRAY_WIDGET_BUTTON_SIZE;
- }
+ if (G_LIKELY (spacing != tray->spacing))
+ {
+ /* set new setting */
+ tray->spacing = spacing;
- /* set the width or height to the allocated size */
- if (XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- child_allocation.height = height;
- else
- child_allocation.width = width;
-
- /* position the arrow button */
- gtk_widget_size_allocate (tray->button, &child_allocation);
+ /* queue a resize */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
}
+}
- /* position all the icons */
- for (li = tray->childeren; li != NULL; li = li->next, i++)
- {
- /* get the child */
- child = li->data;
- _panel_return_val_if_fail (GTK_WIDGET_REALIZED (child), FALSE);
- if (!tray->all_visible && i < tray->n_hidden_childeren)
- {
- child_allocation.x = child_allocation.y = XFCE_TRAY_WIDGET_OFFSCREEN;
- }
- else
- {
- /* position of the child on the tray */
- child_allocation.x = (child_size + XFCE_TRAY_WIDGET_SPACING) * (n / lines) + x_offset;
- child_allocation.y = (child_size + XFCE_TRAY_WIDGET_SPACING) * (n % lines);
+gint
+xfce_tray_widget_get_spacing (XfceTrayWidget *tray)
+{
+ _panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), 0);
- /* increase counter */
- n++;
+ return tray->spacing;
+}
- /* swap coordinates on a vertical panel */
- if (!XFCE_TRAY_WIDGET_IS_HORIZONTAL (tray))
- XFCE_TRAY_WIDGET_SWAP_INT (child_allocation.x, child_allocation.y);
- /* invert the icon order if the arrow button position is right or down */
- if (tray->arrow_position == GTK_ARROW_RIGHT)
- child_allocation.x = width - child_allocation.x - child_size;
- else if (tray->arrow_position == GTK_ARROW_DOWN)
- child_allocation.y = height - child_allocation.y - child_size;
- /* add the tray coordinates and spacing */
- child_allocation.x += x + XFCE_TRAY_WIDGET_SPACING;
- child_allocation.y += y + XFCE_TRAY_WIDGET_SPACING;
- }
+void
+xfce_tray_widget_set_rows (XfceTrayWidget *tray,
+ gint rows)
+{
+ _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
- /* set the child width and height */
- child_allocation.width = child_allocation.height = child_size - 2 * XFCE_TRAY_WIDGET_SPACING;
+ if (G_LIKELY (rows != tray->rows))
+ {
+ /* set new setting */
+ tray->rows = MAX (1, rows);
- /* send the child allocation */
- gtk_widget_size_allocate (child, &child_allocation);
+ /* queue a resize */
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
}
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
}
-static void
-xfce_tray_widget_redraw_destroyed (gpointer user_data)
+gint
+xfce_tray_widget_get_rows (XfceTrayWidget *tray)
{
- XFCE_TRAY_WIDGET (user_data)->idle_redraw_id = 0;
+ _panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), 1);
+
+ return tray->rows;
}
-static void
-xfce_tray_widget_redraw (XfceTrayWidget *tray)
+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');
- /* ignore if there is already a redraw scheduled */
- if (tray->idle_redraw_id != 0 || tray->button == NULL)
- return;
-
- /* schedule an idle redraw */
- tray->idle_redraw_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, xfce_tray_widget_redraw_idle,
- tray, xfce_tray_widget_redraw_destroyed);
+ /* insert the application */
+ g_hash_table_insert (tray->names, g_strdup (name), GUINT_TO_POINTER (hidden ? 1 : 0));
}
void
-xfce_tray_widget_sort (XfceTrayWidget *tray)
+xfce_tray_widget_name_update (XfceTrayWidget *tray,
+ const gchar *name,
+ gboolean hidden)
{
- GSList *li;
- guint n_hidden_childeren = 0;
+ 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');
- /* sort the list */
- tray->childeren = g_slist_sort (tray->childeren, xfce_tray_widget_compare_function);
+ /* replace the old name */
+ g_hash_table_replace (tray->names, g_strdup (name), GUINT_TO_POINTER (hidden ? 1 : 0));
- /* count the number of hidden items again */
+ /* reset counter */
+ n_hidden_childeren = 0;
+
+ /* update the icons */
for (li = tray->childeren; li != NULL; li = li->next)
{
- /* increase counter or break (hidden items are in the beginning of the list) */
- if (xfce_tray_manager_application_get_hidden (GTK_WIDGET (li->data)))
+ 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)
n_hidden_childeren++;
- else
- break;
}
- /* update if changed */
if (tray->n_hidden_childeren != n_hidden_childeren)
{
- /* collapse the button if there are no hidden childeren */
- if (n_hidden_childeren == 0 && tray->button)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tray->button), FALSE);
-
- /* set new value */
+ /* 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 */
- xfce_tray_widget_redraw (tray);
+ gtk_widget_queue_resize (GTK_WIDGET (tray));
}
}
-XfceTrayManager *
-xfce_tray_widget_get_manager (XfceTrayWidget *tray)
+gboolean
+xfce_tray_widget_name_hidden (XfceTrayWidget *tray,
+ const gchar *name)
{
- _panel_return_val_if_fail (XFCE_IS_TRAY_WIDGET (tray), NULL);
+ gpointer p;
- return tray->manager;
-}
+ /* 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);
-
-void
-xfce_tray_widget_set_arrow_position (XfceTrayWidget *tray,
- GtkArrowType arrow_position)
-{
- _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
-
- if (G_LIKELY (tray->arrow_position != arrow_position))
+ /* check the pointer */
+ if (G_UNLIKELY (p == NULL))
{
- /* set property */
- tray->arrow_position = arrow_position;
+ /* add the name */
+ xfce_tray_widget_name_add (tray, name, FALSE);
- /* set orientation of the manager */
- xfce_tray_manager_set_orientation (tray->manager, XFCE_TRAY_WIDGET_GET_ORIENTATION (tray));
-
- /* set the arrow on the button */
- xfce_tray_widget_button_set_arrow (tray);
-
- /* update the tray */
- xfce_tray_widget_redraw (tray);
+ /* do not hide the icon */
+ return FALSE;
}
+ else
+ {
+ return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE);
+ }
}
-void
-xfce_tray_widget_set_size_request (XfceTrayWidget *tray,
- gint size)
+GList *
+xfce_tray_widget_name_list (XfceTrayWidget *tray)
{
- _panel_return_if_fail (XFCE_IS_TRAY_WIDGET (tray));
+ GList *keys;
- if (G_LIKELY (tray->size != size))
- {
- /* set the new size */
- tray->size = size;
+ /* get the hash table keys */
+ keys = g_hash_table_get_keys (tray->names);
- /* redraw the tray */
- xfce_tray_widget_redraw (tray);
- }
+ /* sort the list */
+ keys = g_list_sort (keys, (GCompareFunc) strcmp);
+
+ return keys;
}
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.c
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
===================================================================
--- xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h 2007-11-16 11:36:06 UTC (rev 26318)
+++ xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h 2007-11-16 15:32:40 UTC (rev 26319)
@@ -22,6 +22,7 @@
typedef struct _XfceTrayWidgetClass XfceTrayWidgetClass;
typedef struct _XfceTrayWidget XfceTrayWidget;
+typedef struct _XfceTrayWidgetChild XfceTrayWidgetChild;
#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))
@@ -34,14 +35,36 @@
GtkWidget *xfce_tray_widget_new (void) G_GNUC_MALLOC G_GNUC_INTERNAL;
-void xfce_tray_widget_sort (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+void xfce_tray_widget_add_with_name (XfceTrayWidget *tray,
+ GtkWidget *child,
+ const gchar *name) G_GNUC_INTERNAL;
-XfceTrayManager *xfce_tray_widget_get_manager (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+void xfce_tray_widget_set_arrow_type (XfceTrayWidget *tray,
+ GtkArrowType arrow_type) G_GNUC_INTERNAL;
-void xfce_tray_widget_set_arrow_position (XfceTrayWidget *tray,
- GtkArrowType arrow_position) G_GNUC_INTERNAL;
+GtkArrowType xfce_tray_widget_get_arrow_type (XfceTrayWidget *tray) G_GNUC_INTERNAL;
-void xfce_tray_widget_set_size_request (XfceTrayWidget *tray,
- gint size) G_GNUC_INTERNAL;
+void xfce_tray_widget_set_spacing (XfceTrayWidget *tray,
+ gint spacing) G_GNUC_INTERNAL;
+gint xfce_tray_widget_get_spacing (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+
+void xfce_tray_widget_set_rows (XfceTrayWidget *tray,
+ gint rows) G_GNUC_INTERNAL;
+
+gint xfce_tray_widget_get_rows (XfceTrayWidget *tray) G_GNUC_INTERNAL;
+
+void xfce_tray_widget_name_add (XfceTrayWidget *tray,
+ const gchar *name,
+ gboolean hidden) G_GNUC_INTERNAL;
+
+void xfce_tray_widget_name_update (XfceTrayWidget *tray,
+ const gchar *name,
+ gboolean hidden) G_GNUC_INTERNAL;
+
+gboolean xfce_tray_widget_name_hidden (XfceTrayWidget *tray,
+ const gchar *name) G_GNUC_INTERNAL;
+
+GList *xfce_tray_widget_name_list (XfceTrayWidget *tray) G_GNUC_MALLOC G_GNUC_INTERNAL;
+
#endif /* !__XFCE_TRAY_WIDGET_H__ */
Property changes on: xfce4-panel/trunk/plugins/systray/xfce-tray-widget.h
___________________________________________________________________
Name: svn:keywords
+ Id
More information about the Xfce4-commits
mailing list