← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~bratsche/indicator-sound/icon-placement into lp:indicator-sound

 

Conor Curran has proposed merging lp:~bratsche/indicator-sound/icon-placement into lp:indicator-sound.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)

-- 
https://code.launchpad.net/~bratsche/indicator-sound/icon-placement/+merge/34796
Your team ayatana-commits is subscribed to branch lp:indicator-sound.
=== modified file 'src/common-defs.h'
--- src/common-defs.h	2010-09-03 13:06:00 +0000
+++ src/common-defs.h	2010-09-07 20:22:39 +0000
@@ -41,6 +41,7 @@
 
 #define DBUSMENU_TITLE_MENUITEM_TYPE          	"x-canonical-sound-menu-player-title-type"
 #define DBUSMENU_TITLE_MENUITEM_NAME       			"x-canonical-sound-menu-player-title-name"
+#define DBUSMENU_TITLE_MENUITEM_RUNNING       	"x-canonical-sound-menu-player-title-running"
 
 #define DBUSMENU_SCRUB_MENUITEM_TYPE						"x-canonical-sound-menu-player-scrub-type"
 #define DBUSMENU_SCRUB_MENUITEM_DURATION				"x-canonical-sound-menu-player-scrub-mpris:length"

=== modified file 'src/indicator-sound.c'
--- src/indicator-sound.c	2010-09-06 17:07:15 +0000
+++ src/indicator-sound.c	2010-09-07 20:22:39 +0000
@@ -133,7 +133,7 @@
   IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass);
 
 	g_type_class_add_private (klass, sizeof (IndicatorSoundPrivate));
-	
+
   io_class->get_label = get_label;
   io_class->get_image = get_icon;
   io_class->get_menu  = get_menu;
@@ -154,7 +154,7 @@
   blocked_id = 0;
   initial_mute = FALSE;
   device_available = TRUE;
-	
+
 	IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
 	priv->volume_widget = NULL;
 
@@ -196,8 +196,10 @@
 static GtkImage *
 get_icon (IndicatorObject * io)
 {
-  gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
-  g_debug("At start-up attempting to set the image to %s", current_name);
+	gchar* current_name = g_hash_table_lookup(volume_states,
+	                                          GINT_TO_POINTER(current_state));
+  g_debug("At start-up attempting to set the image to %s",
+          current_name);
   speaker_image = indicator_image_helper(current_name);
   gtk_widget_show(GTK_WIDGET(speaker_image));
   return speaker_image;
@@ -209,18 +211,19 @@
 static GtkMenu *
 get_menu (IndicatorObject * io)
 {
-  DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
+  DbusmenuGtkMenu* menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
+
   DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);
   g_object_set_data (G_OBJECT (client), "indicator", io);
   dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_VOLUME_MENUITEM_TYPE, new_volume_slider_widget);
   dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget);
   dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_METADATA_MENUITEM_TYPE, new_metadata_widget);
   dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TITLE_MENUITEM_TYPE, new_title_widget);
-	dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget);	
-
+	dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget);
 	// register Key-press listening on the menu widget as the slider does not allow this.
   g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), io);
-  return GTK_MENU(menu);
+
+	return GTK_MENU(menu);
 }
 
 static void
@@ -275,19 +278,21 @@
 new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
 {
   g_debug("indicator-sound: new_title_widget");
+  g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+  g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+
+  g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME));
 
   GtkWidget* title = NULL;
 
-  g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
-  g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
-
   title = title_widget_new (newitem);
   GtkMenuItem *menu_title_widget = GTK_MENU_ITEM(title);
 
   gtk_widget_show_all(title);
 
-	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_title_widget, parent);
-
+  dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
+                                  newitem,
+                                  menu_title_widget, parent);
   return TRUE;
 }
 
@@ -322,29 +327,29 @@
   g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
   g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
 
-  volume_widget = volume_widget_new (newitem);	
+  volume_widget = volume_widget_new (newitem);
 	io = g_object_get_data (G_OBJECT (client), "indicator");
 	IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
 	priv->volume_widget = volume_widget;
 
 	GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
 
-  g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL);		
+  g_signal_connect(ido_slider_widget, "style-set", G_CALLBACK(style_changed_cb), NULL);
 	gtk_widget_set_sensitive(ido_slider_widget,
 	                         !initial_mute);
 	gtk_widget_show_all(ido_slider_widget);
 
-	
+
   GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget);
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
 	                                newitem,
 	                                menu_volume_item,
 	                                parent);
-	
+
 	fetch_mute_value_from_dbus();
   fetch_sink_availability_from_dbus(INDICATOR_SOUND (io));
-	
-  return TRUE;	
+
+  return TRUE;
 }
 
 
@@ -376,7 +381,7 @@
       dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
 
 			g_return_if_fail(IS_INDICATOR_SOUND(userdata));
-			
+
     }
   }
   return;
@@ -536,7 +541,7 @@
 fetch_sink_availability_from_dbus(IndicatorSound* self)
 {
 	g_return_if_fail(IS_INDICATOR_SOUND(self));
-	
+
   GError * error = NULL;
   gboolean * available_input;
   available_input = g_new0(gboolean, 1);
@@ -547,7 +552,7 @@
     g_free(available_input);
     return;
   }
-	
+
   device_available = *available_input;
   if (device_available == FALSE) {
     update_state(STATE_SINKS_NONE);
@@ -555,7 +560,7 @@
   }
 
 	IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
-	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));	
+	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
   gtk_widget_set_sensitive(slider_widget, device_available);
 
   g_free(available_input);
@@ -600,7 +605,7 @@
 /*
  We can be sure the service won't send a mute signal unless it has changed !
  UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here.
-*/ 
+*/
 static void
 catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata)
 {
@@ -617,7 +622,7 @@
 	if(priv->volume_widget == NULL){
 		return;
 	}
-	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); 
+	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
   gtk_widget_set_sensitive(slider_widget, !mute_value);
 }
 
@@ -652,8 +657,8 @@
 	if(priv->volume_widget == NULL){
 		return FALSE;
 	}
-	
-	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); 
+
+	GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
   GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget);
   GtkRange* range = (GtkRange*)slider;
   gdouble current_value = gtk_range_get_value(range);

=== modified file 'src/mpris2-controller.vala'
--- src/mpris2-controller.vala	2010-09-06 20:14:15 +0000
+++ src/mpris2-controller.vala	2010-09-07 20:22:39 +0000
@@ -105,7 +105,7 @@
 		if(play_v != null){
 			string state = play_v.get_string();		
 			debug("new playback state = %s", state);			
-			int p = this.determine_play_state(state);
+			TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state);
 			(this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p);			
 		}
 		
@@ -143,29 +143,29 @@
 	}
 	
 	
-	private int determine_play_state(string status){
+	private TransportMenuitem.state determine_play_state(string status){
 		if(status == null)
-			return 1;
+			return TransportMenuitem.state.PAUSED;
 		
 		if(status != null && status == "Playing"){
 			debug("determine play state - state = %s", status);
-			return 0;
+			return TransportMenuitem.state.PLAYING;
 		}
-		return 1;		
+		return TransportMenuitem.state.PAUSED;		
 	}
 	
 	public void initial_update()
 	{
-		int32 status;
+		TransportMenuitem.state update;
 		if(this.player.PlaybackStatus == null){
-			status = 1;
+			update = TransportMenuitem.state.PAUSED;
 		}
 		else{
-			status = determine_play_state(this.player.PlaybackStatus);
+			update = determine_play_state(this.player.PlaybackStatus);
 		}
-		debug("initial update - play state %i", status);
+		debug("initial update - play state %i", (int)update);
 		
-		(this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(status);
+		(this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(update);
 		GLib.HashTable<string, Value?> cleaned_metadata = this.clean_metadata();
 		this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata,
 			                          MetadataMenuitem.attributes_format());
@@ -260,7 +260,7 @@
 				this.mpris2_root.Raise();
 			}
 			catch(DBus.Error e){
-				error("Exception thrown while calling root function Raise - %s", e.message);
+				error("Exception thrown while calling function Raise - %s", e.message);
 			}
 		}
 	}

=== modified file 'src/player-controller.vala'
--- src/player-controller.vala	2010-08-27 11:25:47 +0000
+++ src/player-controller.vala	2010-09-07 20:22:39 +0000
@@ -116,6 +116,8 @@
 		update_state(PlayerController.state.OFFLINE);
 		this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format());
 		this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
+		TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
+		title.toggle_active_triangle(false);					
 	}
 
 	public void update_layout()
@@ -172,6 +174,10 @@
 	{
 		if(this.mpris_bridge.connected() == true){
 			this.update_state(state.CONNECTED);
+			TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem;
+			title.toggle_active_triangle(true);			
+			TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem;
+			transport.change_play_state(TransportMenuitem.state.PAUSED);
 		}
 		else{
 			this.update_state(state.DISCONNECTED);

=== modified file 'src/sound-service.c'
--- src/sound-service.c	2010-09-07 16:57:49 +0000
+++ src/sound-service.c	2010-09-07 20:22:39 +0000
@@ -40,9 +40,15 @@
 {
   if (mainloop != NULL) {
     g_debug("Service shutdown !");
+<<<<<<< TREE
     //TODO: uncomment for release !!
     //close_pulse_activites();
     //g_main_loop_quit(mainloop);
+=======
+    // TODO: uncomment for release !!
+    //close_pulse_activites();
+    //g_main_loop_quit(mainloop);
+>>>>>>> MERGE-SOURCE
   }
   return;
 }

=== modified file 'src/title-menu-item.vala'
--- src/title-menu-item.vala	2010-08-17 16:26:47 +0000
+++ src/title-menu-item.vala	2010-09-07 20:22:39 +0000
@@ -27,6 +27,7 @@
 	{
 		Object(item_type: MENUITEM_TYPE, owner: parent);
 		this.property_set(MENUITEM_NAME, parent.name);		
+		this.property_set_bool(MENUITEM_RUNNING, false);		
 	}
 
 	public override void handle_event(string name, GLib.Value input_value, uint timestamp)
@@ -39,7 +40,11 @@
 			this.owner.mpris_bridge.expose();
 		}		
 	}
-	
+
+	public void toggle_active_triangle(bool update)
+	{
+		this.property_set_bool(MENUITEM_RUNNING, update);				
+	}
 
 	public static HashSet<string> attributes_format()
 	{

=== modified file 'src/title-widget.c'
--- src/title-widget.c	2010-08-25 17:15:56 +0000
+++ src/title-widget.c	2010-09-07 20:22:39 +0000
@@ -4,16 +4,16 @@
 Authors:
     Conor Curran <conor.curran@xxxxxxxxxxxxx>
 
-This program is free software: you can redistribute it and/or modify it 
-under the terms of the GNU General Public License version 3, as published 
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
 by the Free Software Foundation.
 
-This program is distributed in the hope that it will be useful, but 
-WITHOUT ANY WARRANTY; without even the implied warranties of 
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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 
+You should have received a copy of the GNU General Public License along
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
@@ -27,15 +27,12 @@
 #include <gtk/gtk.h>
 #include <libindicator/indicator-image-helper.h>
 
-
-typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
-
 struct _TitleWidgetPrivate
 {
 	GtkWidget* hbox;
 	GtkWidget* name;
-	GtkWidget* player_icon;	
-	DbusmenuMenuitem* twin_item;	
+	GtkWidget* icon;
+	DbusmenuMenuitem* twin_item;
 };
 
 #define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate))
@@ -47,17 +44,21 @@
 static void title_widget_finalize   (GObject *object);
 
 // keyevent consumers
-static gboolean title_widget_button_press_event (GtkWidget *menuitem, 
+static gboolean title_widget_button_press_event (GtkWidget *menuitem,
                                   							 GdkEventButton *event);
 
 // Dbusmenuitem properties update callback
-static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property, 
+static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
                                        GValue* value, gpointer userdata);
 static void title_widget_set_twin_item(	TitleWidget* self,
-                           							DbusmenuMenuitem* twin_item);
+                                        DbusmenuMenuitem* twin_item);
 static void title_widget_style_name_text(TitleWidget* self);
 
-G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_MENU_ITEM);
+static gboolean title_widget_triangle_draw_cb (GtkWidget *widget,
+                                               GdkEventExpose *event,
+                                               gpointer data);
+
+G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_IMAGE_MENU_ITEM);
 
 
 
@@ -65,15 +66,14 @@
 title_widget_class_init (TitleWidgetClass *klass)
 {
 	GObjectClass 			*gobject_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass    *widget_class = GTK_WIDGET_CLASS (klass);
+        GtkWidgetClass    *widget_class = GTK_WIDGET_CLASS (klass);
 
 	widget_class->button_press_event = title_widget_button_press_event;
-	
+
 	g_type_class_add_private (klass, sizeof (TitleWidgetPrivate));
 
 	gobject_class->dispose = title_widget_dispose;
 	gobject_class->finalize = title_widget_finalize;
-
 }
 
 static void
@@ -81,15 +81,25 @@
 {
 	g_debug("TitleWidget::title_widget_init");
 
-	TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
-
-	GtkWidget *hbox;
-
-	hbox = gtk_hbox_new(FALSE, 0);
-	priv->hbox = hbox;
-
-	priv->player_icon = indicator_image_helper("sound_icon");
-	gtk_box_pack_start(GTK_BOX (priv->hbox), priv->player_icon, FALSE, FALSE, 0);		
+	TitleWidgetPrivate *priv = self->priv = TITLE_WIDGET_GET_PRIVATE (self);
+
+	gint padding = 4;
+	gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL);
+
+	gint width, height;
+	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+
+	GtkWidget * icon = gtk_image_new_from_icon_name("sound_icon", GTK_ICON_SIZE_MENU);
+
+	gtk_widget_set_size_request(icon, width
+                                    + 5 /* ref triangle is 5x9 pixels */
+                                    + 2 /* padding */,
+                                    height);
+	gtk_misc_set_alignment(GTK_MISC(icon), 1.0 /* right aligned */, 0.5);
+      	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(self), GTK_WIDGET(icon));
+	gtk_widget_show(icon);
+
+        priv->icon = icon;
 }
 
 static void
@@ -106,30 +116,30 @@
 
 /* Suppress/consume keyevents */
 static gboolean
-title_widget_button_press_event (GtkWidget *menuitem, 
+title_widget_button_press_event (GtkWidget *menuitem,
                                   GdkEventButton *event)
 {
 	g_debug("TitleWidget::menu_press_event");
 	TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(menuitem);
-	
+
 	GValue value = {0};
-  g_value_init(&value, G_TYPE_BOOLEAN);
+        g_value_init(&value, G_TYPE_BOOLEAN);
 
-	g_value_set_boolean(&value, TRUE);	
+	g_value_set_boolean(&value, TRUE);
 	dbusmenu_menuitem_handle_event (priv->twin_item, "Title menu event", &value, 0);
-	
+
 	return FALSE;
 }
 
-static void 
-title_widget_property_update(DbusmenuMenuitem* item, gchar* property, 
+static void
+title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
                                        GValue* value, gpointer userdata)
 {
-	g_return_if_fail (IS_TITLE_WIDGET (userdata));	
+	g_return_if_fail (IS_TITLE_WIDGET (userdata));
 	TitleWidget* mitem = TITLE_WIDGET(userdata);
 	TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(mitem);
-	
-	if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){  
+
+	if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){
 		gtk_label_set_text(GTK_LABEL(priv->name), g_value_get_string(value));
 		title_widget_style_name_text(mitem);
 	}
@@ -139,42 +149,109 @@
 title_widget_set_twin_item(TitleWidget* self,
                            DbusmenuMenuitem* twin_item)
 {
-	TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
-	priv->twin_item = twin_item;
-	g_signal_connect(G_OBJECT(twin_item), "property-changed", 
-	                 G_CALLBACK(title_widget_property_update), self);	
-	priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item, 
-	                                                          DBUSMENU_TITLE_MENUITEM_NAME));
-	gtk_misc_set_padding(GTK_MISC(priv->name), 10, 0);
-	gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, 0);		
-
-	title_widget_style_name_text(self);
-	
-	gtk_widget_show_all (priv->hbox);
-  gtk_container_add (GTK_CONTAINER (self), priv->hbox);	
+  TitleWidgetPrivate *priv = self->priv;
+
+  priv->twin_item = twin_item;
+
+  g_signal_connect (G_OBJECT (twin_item),
+                    "property-changed",
+                    G_CALLBACK (title_widget_property_update),
+                    self);
+  g_signal_connect_after (G_OBJECT (self),
+                         "expose_event",
+                          G_CALLBACK (title_widget_triangle_draw_cb),
+                          twin_item);
+
+  gint padding = 4;
+  gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL);
+
+  // Add the application name
+  priv->hbox = gtk_hbox_new (FALSE, 0);
+
+  priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item,
+                                                            DBUSMENU_TITLE_MENUITEM_NAME));
+  gtk_misc_set_alignment (GTK_MISC (priv->name), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, padding);
+  gtk_widget_show (priv->name);
+
+  title_widget_style_name_text(self);
+
+  gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (priv->hbox));
+  gtk_widget_show (priv->hbox);
 }
-                           
+
 static void
 title_widget_style_name_text(TitleWidget* self)
 {
 	TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
 
 	char* markup;
+
 	markup = g_markup_printf_escaped ("<span size=\"medium\">%s</span>",
 	                                  gtk_label_get_text(GTK_LABEL(priv->name)));
 	gtk_label_set_markup (GTK_LABEL (priv->name), markup);
 	g_free(markup);
 }
- 
+
+static gboolean
+title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+	GtkStyle *style;
+	cairo_t *cr;
+	int x, y, arrow_width, arrow_height;
+
+	if (!GTK_IS_WIDGET (widget)) return FALSE;
+	if (!DBUSMENU_IS_MENUITEM (data)) return FALSE;
+
+	/* render the triangle indicator only if the application is running */
+	if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data),
+	                                           DBUSMENU_TITLE_MENUITEM_RUNNING)){
+		return FALSE;
+	}
+
+	/* get style */
+	style = gtk_widget_get_style (widget);
+
+	/* set arrow position / dimensions */
+	arrow_width = 5; /* the pixel-based reference triangle is 5x9 */
+	arrow_height = 9;
+	x = widget->allocation.x;
+	y = widget->allocation.y + widget->allocation.height/2.0 - (double)arrow_height/2.0;
+
+	/* initialize cairo drawing area */
+	cr = (cairo_t*) gdk_cairo_create (widget->window);
+
+	/* set line width */
+	cairo_set_line_width (cr, 1.0);
+
+	/* cairo drawing code */
+	cairo_move_to (cr, x, y);
+	cairo_line_to (cr, x, y + arrow_height);
+	cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0);
+	cairo_close_path (cr);
+	cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
+	                          style->fg[gtk_widget_get_state(widget)].green/65535.0,
+	                          style->fg[gtk_widget_get_state(widget)].blue/65535.0);
+	cairo_fill (cr);
+
+	/* remember to destroy cairo context to avoid leaks */
+	cairo_destroy (cr);
+
+	return FALSE;
+}
+
  /**
  * transport_new:
  * @returns: a new #TitleWidget.
  **/
-GtkWidget* 
+GtkWidget*
 title_widget_new(DbusmenuMenuitem *item)
 {
-	GtkWidget* widget = g_object_new(TITLE_WIDGET_TYPE, NULL);
+	GtkWidget* widget = g_object_new (TITLE_WIDGET_TYPE,
+                                          NULL);
+        gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), TRUE);
 	title_widget_set_twin_item((TitleWidget*)widget, item);
+
 	return widget;
 }
 

=== modified file 'src/title-widget.h'
--- src/title-widget.h	2010-08-06 12:20:03 +0000
+++ src/title-widget.h	2010-09-07 20:22:39 +0000
@@ -19,7 +19,7 @@
 #ifndef __TITLE_WIDGET_H__
 #define __TITLE_WIDGET_H__
 
-#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkimagemenuitem.h>
 #include <libdbusmenu-gtk/menuitem.h>
 
 G_BEGIN_DECLS
@@ -31,15 +31,17 @@
 #define IS_TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TITLE_WIDGET_TYPE))
 #define TITLE_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TITLE_WIDGET_TYPE, TitleWidgetClass))
 
-typedef struct _TitleWidget      TitleWidget;
-typedef struct _TitleWidgetClass TitleWidgetClass;
+typedef struct _TitleWidget        TitleWidget;
+typedef struct _TitleWidgetClass   TitleWidgetClass;
+typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
 
 struct _TitleWidgetClass {
-	  GtkMenuItemClass parent_class;
+  GtkImageMenuItemClass parent_class;
 };
 
 struct _TitleWidget {
-	  GtkMenuItem parent;
+  GtkImageMenuItem parent;
+  TitleWidgetPrivate *priv;
 };
 
 GType title_widget_get_type (void);

=== modified file 'src/transport-menu-item.vala'
--- src/transport-menu-item.vala	2010-08-12 12:21:57 +0000
+++ src/transport-menu-item.vala	2010-09-07 20:22:39 +0000
@@ -28,6 +28,11 @@
 		PLAY_PAUSE,
 		NEXT
 	}
+
+	public enum state{
+		PLAYING,
+		PAUSED
+	}
 	
 	public TransportMenuitem(PlayerController parent)
   {
@@ -35,9 +40,9 @@
 		this.property_set_int(MENUITEM_PLAY_STATE, 1);		
 	}
 
-	public void change_play_state(int state)
+	public void change_play_state(state update)
 	{
-		this.property_set_int(MENUITEM_PLAY_STATE, state);	
+		this.property_set_int(MENUITEM_PLAY_STATE, update);	
 	}
 	
 	public override void handle_event(string name, GLib.Value input_value, uint timestamp)
@@ -54,4 +59,6 @@
 		attrs.add(MENUITEM_PLAY_STATE);
 		return attrs;
 	}	
+
+	
 }
\ No newline at end of file

=== modified file 'vapi/common-defs.vapi'
--- vapi/common-defs.vapi	2010-09-03 13:06:00 +0000
+++ vapi/common-defs.vapi	2010-09-07 20:22:39 +0000
@@ -36,6 +36,7 @@
 namespace DbusmenuTitle{
 	public const string MENUITEM_TYPE;
 	public const string MENUITEM_NAME;
+	public const string MENUITEM_RUNNING;
 }
 
 [CCode (cheader_filename = "common-defs.h")]