Index: ChangeLog.pre-1-4
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog.pre-1-4,v
retrieving revision 1.1
diff -u -r1.1 ChangeLog.pre-1-4
--- ChangeLog.pre-1-4	9 Jun 2003 17:30:49 -0000	1.1
+++ ChangeLog.pre-1-4	7 Jul 2003 04:18:12 -0000
@@ -1,3 +1,21 @@
+2003-07-04  Maxx Cao  <maxx.cao@sun.com>
+	
+	** For bug #41839	
+
+	* mail-display.c (do_attachment_header): Attachment buttons made 
+	accessable with keyboard (focusable). "Inline" button is disabled 
+	when attachment can't be viewed inline.
+	
+	* mail-display.c (do_signature): Signature button made accessable
+	with keyboard (focusable)
+
+	* mail-display.c (button_press): Function changed to an event 
+	callback (originally gtkbutton signal callback)
+
+	* mail-display.c (popup_menu_placement_callback): Function added
+	to place popup menu (of attachment) beside button when activated 
+	by keyboard
+
 2003-06-02  Not Zed  <NotZed@Ximian.com>
 
 	** This and jeffs patch for #43862.
Index: mail-display.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-display.c,v
retrieving revision 1.283
diff -u -r1.283 mail-display.c
--- mail-display.c	1 Jul 2003 18:43:21 -0000	1.283
+++ mail-display.c	7 Jul 2003 04:18:15 -0000
@@ -50,6 +50,7 @@
 #include <bonobo/bonobo-widget.h>
 #include <bonobo/bonobo-socket.h>
 
+#include <gdk/gdkkeysyms.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 #include <gal/util/e-util.h>
@@ -435,25 +436,45 @@
 	mail_display_queue_redisplay (md);
 }
 
-static void
-button_press (GtkWidget *widget, CamelMimePart *part)
+static gboolean
+button_press (GtkWidget *widget, GdkEvent *event, CamelMimePart *part)
 {
 	MailDisplay *md;
-	
+
+	if (event->type == GDK_BUTTON_PRESS)
+		g_signal_stop_emission_by_name (widget, "button_press_event");
+	else if (event->type == GDK_KEY_PRESS && event->key.keyval != GDK_Return)
+		return FALSE;
+
 	md = g_object_get_data ((GObject *) widget, "MailDisplay");
 	if (md == NULL) {
 		g_warning ("No MailDisplay on button!");
-		return;
+		return TRUE;
 	}
 	
 	mail_part_toggle_displayed (part, md);
 	mail_display_queue_redisplay (md);
+
+	return TRUE;
+}
+
+static void
+popup_menu_placement_callback(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
+{
+	GtkWidget *widget = (GtkWidget*) user_data;
+
+	gdk_window_get_origin (gtk_widget_get_parent_window (widget), x, y);
+	*x += widget->allocation.x + widget->allocation.width;
+	*y += widget->allocation.y;
+
+	return;
 }
 
 static gboolean
-pixmap_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+pixmap_press (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 {
 	EPopupMenu *menu;
+	GtkMenu *gtk_menu;
 	EPopupMenu save_item = E_POPUP_ITEM (N_("Save Attachment..."), G_CALLBACK (save_cb), 0);
 	EPopupMenu view_item = E_POPUP_ITEM (N_("View Inline"), G_CALLBACK (inline_cb), 2);
 	EPopupMenu open_item = E_POPUP_ITEM (N_("Open in %s..."), G_CALLBACK (launch_cb), 1);
@@ -462,24 +483,28 @@
 	MailMimeHandler *handler;
 	int mask = 0, i, nitems;
 	
+	if (event->type == GDK_BUTTON_PRESS) {
 #ifdef USE_OLD_DISPLAY_STYLE
-	if (event->button != 3) {
-		gtk_propagate_event (GTK_WIDGET (user_data),
-				     (GdkEvent *)event);
-		return TRUE;
-	}
+		if (event->button.button != 3) {
+			gtk_propagate_event (GTK_WIDGET (user_data),
+					     (GdkEvent *)event);
+			return TRUE;
+		}
 #endif
-	
-	if (event->button != 1 && event->button != 3) {
-		gtk_propagate_event (GTK_WIDGET (user_data),
-				     (GdkEvent *)event);
-		return TRUE;
+		
+		if (event->button.button != 1 && event->button.button != 3) {
+			gtk_propagate_event (GTK_WIDGET (user_data),
+					     (GdkEvent *)event);
+			return TRUE;
+		}
+		/* Stop the signal, since we don't want the button's class method to
+		   mess up our popup. */
+		g_signal_stop_emission_by_name (widget, "button_press_event");
+	} else {
+		if (event->key.keyval != GDK_Return)
+			return FALSE;
 	}
 	
-	/* Stop the signal, since we don't want the button's class method to
-	   mess up our popup. */
-	g_signal_stop_emission_by_name (widget, "button_press_event");
-	
 	part = g_object_get_data ((GObject *) widget, "CamelMimePart");
 	handler = mail_lookup_handler (g_object_get_data ((GObject *) widget, "mime_type"));
 	
@@ -540,7 +565,13 @@
 		mask |= 1;
 	}
 	
-	e_popup_menu_run (menu, (GdkEvent *)event, mask, 0, widget);
+	gtk_menu = e_popup_menu_create (menu, mask, 0, widget);
+	e_auto_kill_popup_menu_on_selection_done (gtk_menu);
+
+	if (event->type == GDK_BUTTON_PRESS)
+		gtk_menu_popup (gtk_menu, NULL, NULL, NULL, (gpointer)widget, event->button.button, event->button.time);
+	else
+		gtk_menu_popup (gtk_menu, NULL, NULL, popup_menu_placement_callback, (gpointer)widget, 0, event->key.time);
 	
 	for (i = 1; i < nitems; i++)
 		g_free (menu[i].name);
@@ -1039,12 +1070,16 @@
 	mainbox = gtk_hbox_new (FALSE, 0);
 	
 	button = gtk_button_new ();
-	GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
 	g_object_set_data ((GObject *) button, "MailDisplay", md);
 	
 	handler = mail_lookup_handler (eb->type);
-	if (handler && handler->builtin)
-		g_signal_connect (button, "clicked", G_CALLBACK (button_press), part);
+	if (handler && handler->builtin) {
+		g_signal_connect (button, "button_press_event", G_CALLBACK (button_press), part);
+		g_signal_connect (button, "key_press_event", G_CALLBACK (button_press), part);
+	} else {
+		gtk_widget_set_sensitive (button, FALSE);
+		GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+	}
 	
 	/* Drag & Drop */
 	drag_types[DND_TARGET_TYPE_PART_MIME_TYPE].target = header_content_type_simple (part->content_type);
@@ -1072,7 +1107,6 @@
 	gtk_container_add (GTK_CONTAINER (button), hbox);
 	
 	popup = gtk_button_new ();
-	GTK_WIDGET_UNSET_FLAGS (popup, GTK_CAN_FOCUS);
 	gtk_container_add (GTK_CONTAINER (popup),
 			   gtk_arrow_new (GTK_ARROW_DOWN,
 					  GTK_SHADOW_ETCHED_IN));
@@ -1082,6 +1116,7 @@
 	g_object_set_data_full ((GObject *) popup, "mime_type", g_strdup (eb->type), (GDestroyNotify) g_free);
 	
 	g_signal_connect (popup, "button_press_event", G_CALLBACK (pixmap_press), md->scroll);
+	g_signal_connect (popup, "key_press_event", G_CALLBACK (pixmap_press), md->scroll);
 	
 	gtk_box_pack_start (GTK_BOX (mainbox), button, TRUE, TRUE, 0);
 	gtk_box_pack_start (GTK_BOX (mainbox), popup, TRUE, TRUE, 0);
@@ -1176,9 +1211,10 @@
 	g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc) pixbuf_gen_idle, pbl, NULL);
 	
 	button = gtk_button_new ();
-	GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
 	g_object_set_data ((GObject *) button, "MailDisplay", md);
-	g_signal_connect (button, "clicked", G_CALLBACK (button_press), part);
+	g_signal_connect (button, "button_press_event", G_CALLBACK (button_press), part);
+	g_signal_connect (button, "key_press_event", G_CALLBACK (button_press), part);
+
 	gtk_container_add (GTK_CONTAINER (button), pbl->pixmap);
 	gtk_widget_show_all (button);
 	gtk_container_add (GTK_CONTAINER (eb), button);
