[gnome-panel] [na] Make location of standard status icons predictable
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel] [na] Make location of standard status icons predictable
- Date: Tue, 9 Mar 2010 05:43:58 +0000 (UTC)
commit dd041a313fa563ae9a01dccdca0509fae1efbdb1
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Mar 9 06:39:59 2010 +0100
[na] Make location of standard status icons predictable
We define a list of known standard status icons, and we make sure they
always appear in the same order in the notification area.
All other icons appear on the left (in LTR environments) of those known
standard status icons.
More information on this can be found at:
http://live.gnome.org/Features/StandardIconOrdering
https://bugzilla.gnome.org/show_bug.cgi?id=583115
applets/notification_area/na-tray-child.c | 85 +++++++++++++++++++++++
applets/notification_area/na-tray-child.h | 17 +++--
applets/notification_area/na-tray.c | 106 ++++++++++++++++++++++++++++-
3 files changed, 199 insertions(+), 9 deletions(-)
---
diff --git a/applets/notification_area/na-tray-child.c b/applets/notification_area/na-tray-child.c
index d3195bc..576efbd 100644
--- a/applets/notification_area/na-tray-child.c
+++ b/applets/notification_area/na-tray-child.c
@@ -428,3 +428,88 @@ na_tray_child_force_redraw (NaTrayChild *child)
#endif
}
}
+
+/* from libwnck/xutils.c, comes as LGPLv2+ */
+static char *
+latin1_to_utf8 (const char *latin1)
+{
+ GString *str;
+ const char *p;
+
+ str = g_string_new (NULL);
+
+ p = latin1;
+ while (*p)
+ {
+ g_string_append_unichar (str, (gunichar) *p);
+ ++p;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+/* derived from libwnck/xutils.c, comes as LGPLv2+ */
+static void
+_get_wmclass (Display *xdisplay,
+ Window xwindow,
+ char **res_class,
+ char **res_name)
+{
+ XClassHint ch;
+
+ ch.res_name = NULL;
+ ch.res_class = NULL;
+
+ gdk_error_trap_push ();
+ XGetClassHint (xdisplay, xwindow, &ch);
+ gdk_error_trap_pop ();
+
+ if (res_class)
+ *res_class = NULL;
+
+ if (res_name)
+ *res_name = NULL;
+
+ if (ch.res_name)
+ {
+ if (res_name)
+ *res_name = latin1_to_utf8 (ch.res_name);
+
+ XFree (ch.res_name);
+ }
+
+ if (ch.res_class)
+ {
+ if (res_class)
+ *res_class = latin1_to_utf8 (ch.res_class);
+
+ XFree (ch.res_class);
+ }
+}
+
+/**
+ * na_tray_child_get_wm_class;
+ * @child: a #NaTrayChild
+ * @res_name: return location for a string containing the application name of
+ * @child, or %NULL
+ * @res_class: return location for a string containing the application class of
+ * @child, or %NULL
+ *
+ * Fetches the resource associated with @child.
+ */
+void
+na_tray_child_get_wm_class (NaTrayChild *child,
+ char **res_name,
+ char **res_class)
+{
+ GdkDisplay *display;
+
+ g_return_if_fail (NA_IS_TRAY_CHILD (child));
+
+ display = gtk_widget_get_display (GTK_WIDGET (child));
+
+ _get_wmclass (GDK_DISPLAY_XDISPLAY (display),
+ child->icon_window,
+ res_class,
+ res_name);
+}
diff --git a/applets/notification_area/na-tray-child.h b/applets/notification_area/na-tray-child.h
index c174abe..5e4aba8 100644
--- a/applets/notification_area/na-tray-child.h
+++ b/applets/notification_area/na-tray-child.h
@@ -55,13 +55,16 @@ struct _NaTrayChildClass
GType na_tray_child_get_type (void);
-GtkWidget *na_tray_child_new (GdkScreen *screen,
- Window icon_window);
-char *na_tray_child_get_title (NaTrayChild *child);
-gboolean na_tray_child_has_alpha (NaTrayChild *child);
-void na_tray_child_set_composited (NaTrayChild *child,
- gboolean composited);
-void na_tray_child_force_redraw (NaTrayChild *child);
+GtkWidget *na_tray_child_new (GdkScreen *screen,
+ Window icon_window);
+char *na_tray_child_get_title (NaTrayChild *child);
+gboolean na_tray_child_has_alpha (NaTrayChild *child);
+void na_tray_child_set_composited (NaTrayChild *child,
+ gboolean composited);
+void na_tray_child_force_redraw (NaTrayChild *child);
+void na_tray_child_get_wm_class (NaTrayChild *child,
+ char **res_name,
+ char **res_class);
G_END_DECLS
diff --git a/applets/notification_area/na-tray.c b/applets/notification_area/na-tray.c
index 026fc42..ebd4ce4 100644
--- a/applets/notification_area/na-tray.c
+++ b/applets/notification_area/na-tray.c
@@ -117,6 +117,105 @@ get_tray (TraysScreen *trays_screen)
return trays_screen->all_trays->data;
}
+const char *ordered_roles[] = {
+ "keyboard",
+ "volume",
+ "bluetooth",
+ "network",
+ "battery",
+ NULL
+};
+
+const char *wmclass_roles[] = {
+ "Bluetooth-applet", "bluetooth",
+ "Gnome-volume-control-applet", "volume",
+ "Nm-applet", "network",
+ "Gnome-power-manager", "battery",
+ "keyboard", "keyboard",
+ NULL,
+};
+
+static const char *
+find_role (const char *wmclass)
+{
+ int i;
+
+ for (i = 0; wmclass_roles[i]; i += 2)
+ {
+ if (strcmp (wmclass, wmclass_roles[i]) == 0)
+ return wmclass_roles[i + 1];
+ }
+
+ return NULL;
+}
+
+static int
+find_role_position (const char *role)
+{
+ int i;
+
+ for (i = 0; ordered_roles[i]; i++)
+ {
+ if (strcmp (role, ordered_roles[i]) == 0)
+ break;
+ }
+
+ return i + 1;
+}
+
+static int
+find_icon_position (NaTray *tray,
+ GtkWidget *icon)
+{
+ NaTrayPrivate *priv;
+ int position;
+ char *class_a;
+ const char *role;
+ int role_position;
+ GList *l, *children;
+
+ /* We insert the icons with a known roles in a specific order (the one
+ * defined by ordered_roles), and all other icons at the beginning of the box
+ * (left in LTR). */
+
+ priv = tray->priv;
+ position = 0;
+
+ class_a = NULL;
+ na_tray_child_get_wm_class (NA_TRAY_CHILD (icon), NULL, &class_a);
+ if (!class_a)
+ return position;
+
+ role = find_role (class_a);
+ g_free (class_a);
+ if (!role)
+ return position;
+
+ role_position = find_role_position (role);
+ g_object_set_data (G_OBJECT (icon), "role-position", GINT_TO_POINTER (role_position));
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ for (l = g_list_last (children); l; l = l->prev)
+ {
+ GtkWidget *child = l->data;
+ int rp;
+
+ rp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "role-position"));
+ if (rp == 0 || rp < role_position)
+ {
+ position = g_list_index (children, child) + 1;
+ break;
+ }
+ }
+ g_list_free (children);
+
+ /* should never happen, but it doesn't hurt to be on the safe side */
+ if (position < 0)
+ position = 0;
+
+ return position;
+}
+
static void
tray_added (NaTrayManager *manager,
GtkWidget *icon,
@@ -124,6 +223,7 @@ tray_added (NaTrayManager *manager,
{
NaTray *tray;
NaTrayPrivate *priv;
+ int position;
tray = get_tray (trays_screen);
if (tray == NULL)
@@ -132,10 +232,12 @@ tray_added (NaTrayManager *manager,
priv = tray->priv;
g_assert (priv->trays_screen == trays_screen);
-
+
g_hash_table_insert (trays_screen->icon_table, icon, tray);
- gtk_box_pack_end (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
+ position = find_icon_position (tray, icon);
+ gtk_box_pack_start (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (priv->box), icon, position);
gtk_widget_show (icon);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]