Ethereal-dev: [ethereal-dev] Right button menus

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Jerry Talkington <jerryt@xxxxxxxxxx>
Date: Mon, 20 Dec 1999 13:31:05 -0800
Here are three patches, which all provide right click menus.  The first one
is just a static menu, which is attached to the packet list and the tree
view.  The second one does automagic adding of menu items when they are set
sensitive, but it could cause confusion with the ordering of menu items,
depending on how it's called.  The third has seperate static menus for each pane.

All three have the problem that the cursor must be above a top-level tree
item to popup the window.  I suppose that one could attach the menu to the
lower widgets also, but I didn't try it.  Trying to attach the menu to the
tv_scrollw had some funky results...

-- 
Jerry Talkington
NetCache Escalation Engineer
Network Appliance, Inc.

"I believe the children are our future: nasty, brutish and short."
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.76
diff -u -r1.76 main.c
--- main.c	1999/12/16 06:20:16	1.76
+++ main.c	1999/12/20 17:45:55
@@ -1239,6 +1239,8 @@
   }
   gtk_widget_set_usize(packet_list, -1, pl_size);
   gtk_paned_add1(GTK_PANED(u_pane), pkt_scrollw);
+  gtk_signal_connect_object(GTK_OBJECT(packet_list), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), GTK_OBJECT(popup_menu_object));
   gtk_widget_show(packet_list);
   
   /* Tree view */
@@ -1258,6 +1260,8 @@
 
   gtk_signal_connect(GTK_OBJECT(tree_view), "selection_changed",
     GTK_SIGNAL_FUNC(tree_view_cb), NULL);
+  gtk_signal_connect_object(GTK_OBJECT(tree_view), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), GTK_OBJECT(popup_menu_object));
   gtk_widget_show(tree_view);
 
   item_style = gtk_style_new();
Index: gtk/menu.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.c,v
retrieving revision 1.12
diff -u -r1.12 menu.c
--- menu.c	1999/12/10 07:04:30	1.12
+++ menu.c	1999/12/20 17:45:55
@@ -74,6 +74,7 @@
                "<LastBranch>"     -> create a right justified branch 
     */
 
+/* main menu */
 static GtkItemFactoryEntry menu_items[] =
 {
   {"/_File", NULL, NULL, 0, "<Branch>" },
@@ -122,8 +123,25 @@
 /* calculate the number of menu_items */
 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
 
+/* packet list popup */
+static GtkItemFactoryEntry popup_menu_items[] =
+{
+	{"/Match Selected", NULL, GTK_MENU_FUNC(match_selected_cb), 0, NULL},
+	{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
+	{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
+	{"/<separator>", NULL, NULL, 0, "<Separator>"},
+	{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
+	{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
+  	{"/Print Packet", NULL, GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL},
+	{"/<separator>", NULL, NULL, 0, "<Separator>"},
+	{"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
+	{"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL}
+};
+
+
 static int initialize = TRUE;
 static GtkItemFactory *factory = NULL;
+static GtkItemFactory *popup_menu_factory;
 
 void
 get_main_menu(GtkWidget ** menubar, GtkAccelGroup ** table) {
@@ -147,7 +165,10 @@
     initialize = FALSE;
 
     factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
+    popup_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
     gtk_item_factory_create_items_ac(factory, nmenu_items, menu_items, NULL,2);
+    gtk_item_factory_create_items_ac(popup_menu_factory, sizeof(popup_menu_items)/sizeof(popup_menu_items[0]), popup_menu_items, NULL,2);
+    popup_menu_object = popup_menu_factory->widget;
     set_menu_sensitivity("/File/Close", FALSE);
     set_menu_sensitivity("/File/Save", FALSE);
     set_menu_sensitivity("/File/Save As...", FALSE);
@@ -173,17 +194,44 @@
 void
 set_menu_sensitivity (gchar *path, gint val) {
   GtkWidget *menu;
+  gchar *shortpath = rindex(path, '/');
 
   if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
     gtk_widget_set_sensitive(menu, val);
+  
+  if ((menu = gtk_item_factory_get_widget(popup_menu_factory, shortpath)) != NULL)
+    gtk_widget_set_sensitive(menu, val);
 }
 
 void
 set_menu_object_data (gchar *path, gchar *key, gpointer data) {
   GtkWidget *menu;
+  gchar *shortpath = rindex(path, '/');
   
   if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
     gtk_object_set_data(GTK_OBJECT(menu), key, data);
+  
+  if ((menu = gtk_item_factory_get_widget(popup_menu_factory, shortpath)) != NULL)
+    gtk_object_set_data(GTK_OBJECT(menu), key, data);
+    
 }
 
+void
+popup_menu_handler(GtkWidget *widget, GdkEvent *event)
+{
+	GtkWidget *menu = NULL;
+	GdkEventButton *event_button = NULL;
 
+	if(widget == NULL || event == NULL) {
+		return;
+	}
+	
+	menu = widget;
+	if(event->type == GDK_BUTTON_PRESS) {
+		event_button = (GdkEventButton *) event;
+		
+		if(event_button->button == 3) {
+			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time);
+		}
+	}
+}
Index: gtk/menu.h
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.h,v
retrieving revision 1.1
diff -u -r1.1 menu.h
--- menu.h	1999/09/01 03:04:23	1.1
+++ menu.h	1999/12/20 17:45:55
@@ -38,7 +38,9 @@
 void set_menu_sensitivity (gchar *, gint);
 void set_menu_object_data (gchar *path, gchar *key, gpointer data);
 void menus_create (GtkMenuEntry *, int);
+void popup_menu_handler(GtkWidget *widget, GdkEvent *event);
 
+GtkWidget           *popup_menu_object;
 
 #ifdef __cplusplus
 }
Index: file.c
===================================================================
RCS file: /cvsroot/ethereal/file.c,v
retrieving revision 1.141
diff -u -r1.141 file.c
--- file.c	1999/12/19 09:22:19	1.141
+++ file.c	1999/12/20 19:38:45
@@ -336,8 +336,6 @@
   cf->fh = filed_open(cf->filed, "r");
   cf->unfiltered_count = cf->count;
   cf->current_frame = cf->first_displayed;
-  /* Make the first row the selected row. */
-  gtk_clist_select_row(GTK_CLIST(packet_list), 0, -1);
   thaw_clist(cf);
 
   gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE);
@@ -362,6 +360,9 @@
   set_menu_sensitivity("/Display/Go To Frame...", TRUE);
   set_menu_sensitivity("/Tools/Graph", TRUE);
   set_menu_sensitivity("/Tools/Summary", TRUE);
+
+  /* Make the first row the selected row. */
+  gtk_signal_emit_by_name(GTK_OBJECT(packet_list), "select_row", 0);
 
   if (!success) {
     /* Put up a message box noting that the read failed somewhere along
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.76
diff -u -r1.76 main.c
--- main.c	1999/12/16 06:20:16	1.76
+++ main.c	1999/12/20 19:38:48
@@ -1239,6 +1239,8 @@
   }
   gtk_widget_set_usize(packet_list, -1, pl_size);
   gtk_paned_add1(GTK_PANED(u_pane), pkt_scrollw);
+  gtk_signal_connect_object(GTK_OBJECT(packet_list), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), GTK_OBJECT(popup_menu_object));
   gtk_widget_show(packet_list);
   
   /* Tree view */
@@ -1258,6 +1260,8 @@
 
   gtk_signal_connect(GTK_OBJECT(tree_view), "selection_changed",
     GTK_SIGNAL_FUNC(tree_view_cb), NULL);
+  gtk_signal_connect_object(GTK_OBJECT(tree_view), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), GTK_OBJECT(popup_menu_object));
   gtk_widget_show(tree_view);
 
   item_style = gtk_style_new();
Index: gtk/menu.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.c,v
retrieving revision 1.12
diff -u -r1.12 menu.c
--- menu.c	1999/12/10 07:04:30	1.12
+++ menu.c	1999/12/20 19:38:48
@@ -74,6 +74,7 @@
                "<LastBranch>"     -> create a right justified branch 
     */
 
+/* main menu */
 static GtkItemFactoryEntry menu_items[] =
 {
   {"/_File", NULL, NULL, 0, "<Branch>" },
@@ -122,8 +123,23 @@
 /* calculate the number of menu_items */
 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
 
+/* packet list popup */
+static GtkItemFactoryEntry popup_menu_items[] =
+{
+	{"/Match Selected", NULL, GTK_MENU_FUNC(match_selected_cb), 0, NULL},
+	{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
+	{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
+	{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
+	{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
+  	{"/Print Packet", NULL, GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL},
+	{"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
+	{"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL}
+};
+
+
 static int initialize = TRUE;
 static GtkItemFactory *factory = NULL;
+static GtkItemFactory *popup_menu_factory;
 
 void
 get_main_menu(GtkWidget ** menubar, GtkAccelGroup ** table) {
@@ -146,6 +162,10 @@
   if (initialize) {
     initialize = FALSE;
 
+    /* popup */
+    popup_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+    popup_menu_object = popup_menu_factory->widget;
+    
     factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
     gtk_item_factory_create_items_ac(factory, nmenu_items, menu_items, NULL,2);
     set_menu_sensitivity("/File/Close", FALSE);
@@ -167,23 +187,68 @@
     set_menu_sensitivity("/Tools/Follow TCP Stream", FALSE);
     set_menu_sensitivity("/Tools/Graph", FALSE);
     set_menu_sensitivity("/Tools/Summary", FALSE);
+    /* popup items have to be explicitly set to true */
+    set_menu_sensitivity("/Edit/Filters...", TRUE);
   }
 }
 
 void
 set_menu_sensitivity (gchar *path, gint val) {
   GtkWidget *menu;
+  gchar *shortpath = rindex(path, '/');
 
   if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
     gtk_widget_set_sensitive(menu, val);
+  
+  if ((menu = gtk_item_factory_get_widget(popup_menu_factory, shortpath)) != NULL) {
+  	if(val == FALSE) {
+		gtk_item_factory_delete_item(popup_menu_factory, shortpath);
+	} else {
+		gtk_widget_set_sensitive(menu, val);
+	}
+  } else if (val == TRUE) {
+  	GtkItemFactoryEntry *newitem = NULL;
+	int i = 0;
+
+	for (i = 0; i < (sizeof(popup_menu_items)/sizeof(popup_menu_items[0])); i++) {
+		newitem = &popup_menu_items[i];
+		if(strcmp(shortpath, newitem->path) == 0) {
+			gtk_item_factory_create_item(popup_menu_factory, newitem, NULL, 2);
+			break;
+		}
+	}
+  }
 }
 
 void
 set_menu_object_data (gchar *path, gchar *key, gpointer data) {
   GtkWidget *menu;
+  gchar *shortpath = rindex(path, '/');
   
   if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
     gtk_object_set_data(GTK_OBJECT(menu), key, data);
+  
+  if ((menu = gtk_item_factory_get_widget(popup_menu_factory, shortpath)) != NULL)
+    gtk_object_set_data(GTK_OBJECT(menu), key, data);
+    
 }
 
+void
+popup_menu_handler(GtkWidget *widget, GdkEvent *event)
+{
+	GtkWidget *menu = NULL;
+	GdkEventButton *event_button = NULL;
 
+	if(widget == NULL || event == NULL) {
+		return;
+	}
+	
+	menu = widget;
+	if(event->type == GDK_BUTTON_PRESS) {
+		event_button = (GdkEventButton *) event;
+		
+		if(event_button->button == 3) {
+			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time);
+		}
+	}
+}
Index: gtk/menu.h
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.h,v
retrieving revision 1.1
diff -u -r1.1 menu.h
--- menu.h	1999/09/01 03:04:23	1.1
+++ menu.h	1999/12/20 19:38:48
@@ -38,7 +38,9 @@
 void set_menu_sensitivity (gchar *, gint);
 void set_menu_object_data (gchar *path, gchar *key, gpointer data);
 void menus_create (GtkMenuEntry *, int);
+void popup_menu_handler(GtkWidget *widget, GdkEvent *event);
 
+GtkWidget           *popup_menu_object;
 
 #ifdef __cplusplus
 }
Index: file.c
===================================================================
RCS file: /cvsroot/ethereal/file.c,v
retrieving revision 1.141
diff -u -r1.141 file.c
--- file.c	1999/12/19 09:22:19	1.141
+++ file.c	1999/12/20 21:04:26
@@ -336,8 +336,6 @@
   cf->fh = filed_open(cf->filed, "r");
   cf->unfiltered_count = cf->count;
   cf->current_frame = cf->first_displayed;
-  /* Make the first row the selected row. */
-  gtk_clist_select_row(GTK_CLIST(packet_list), 0, -1);
   thaw_clist(cf);
 
   gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE);
@@ -362,6 +360,9 @@
   set_menu_sensitivity("/Display/Go To Frame...", TRUE);
   set_menu_sensitivity("/Tools/Graph", TRUE);
   set_menu_sensitivity("/Tools/Summary", TRUE);
+
+  /* Make the first row the selected row. */
+  gtk_signal_emit_by_name(GTK_OBJECT(packet_list), "select_row", 0);
 
   if (!success) {
     /* Put up a message box noting that the read failed somewhere along
Index: gtk/keys.h
===================================================================
RCS file: /cvsroot/ethereal/gtk/keys.h,v
retrieving revision 1.8
diff -u -r1.8 keys.h
--- keys.h	1999/12/09 20:41:41	1.8
+++ keys.h	1999/12/20 21:04:26
@@ -41,4 +41,8 @@
 
 #define PLUGINS_DFILTER_TE        "plugins_dfilter_te"
 
+#define PM_MENU_LIST_KEY	  "popup_menu_menu_list"
+#define PM_PACKET_LIST_KEY	  "popup_menu_packet_list"
+#define PM_TREE_VIEW_KEY	  "popup_menu_tree_view"
+
 #endif
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.76
diff -u -r1.76 main.c
--- main.c	1999/12/16 06:20:16	1.76
+++ main.c	1999/12/20 21:04:27
@@ -1239,6 +1239,8 @@
   }
   gtk_widget_set_usize(packet_list, -1, pl_size);
   gtk_paned_add1(GTK_PANED(u_pane), pkt_scrollw);
+  gtk_signal_connect_object(GTK_OBJECT(packet_list), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
   gtk_widget_show(packet_list);
   
   /* Tree view */
@@ -1258,6 +1260,8 @@
 
   gtk_signal_connect(GTK_OBJECT(tree_view), "selection_changed",
     GTK_SIGNAL_FUNC(tree_view_cb), NULL);
+  gtk_signal_connect_object(GTK_OBJECT(tree_view), "button_press_event",
+    GTK_SIGNAL_FUNC(popup_menu_handler), gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
   gtk_widget_show(tree_view);
 
   item_style = gtk_style_new();
Index: gtk/menu.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.c,v
retrieving revision 1.12
diff -u -r1.12 menu.c
--- menu.c	1999/12/10 07:04:30	1.12
+++ menu.c	1999/12/20 21:04:28
@@ -28,6 +28,7 @@
 #endif
 
 #include <gtk/gtk.h>
+#include <glib.h>
 
 #include <string.h>
 #include <stdio.h>
@@ -48,6 +49,7 @@
 #include "print.h"
 #include "follow.h"
 #include "colors.h"
+#include "keys.h"
 
 
 GtkAccelGroup *grp;
@@ -74,6 +76,7 @@
                "<LastBranch>"     -> create a right justified branch 
     */
 
+/* main menu */
 static GtkItemFactoryEntry menu_items[] =
 {
   {"/_File", NULL, NULL, 0, "<Branch>" },
@@ -122,16 +125,48 @@
 /* calculate the number of menu_items */
 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
 
+/* packet list popup */
+static GtkItemFactoryEntry packet_list_menu_items[] =
+{
+	{"/Match Selected", NULL, GTK_MENU_FUNC(match_selected_cb), 0, NULL},
+	{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
+	{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
+	{"/<separator>", NULL, NULL, 0, "<Separator>"},
+	{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
+	{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
+  	{"/Print Packet", NULL, GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL},
+	{"/<separator>", NULL, NULL, 0, "<Separator>"},
+	{"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
+	{"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL}
+};
+
+static GtkItemFactoryEntry tree_view_menu_items[] =
+{
+	{"/Match Selected", NULL, GTK_MENU_FUNC(match_selected_cb), 0, NULL},
+	{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
+	{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
+	{"/<separator>", NULL, NULL, 0, "<Separator>"},
+	{"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
+	{"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL}
+};
+
+
 static int initialize = TRUE;
 static GtkItemFactory *factory = NULL;
+static GtkItemFactory *packet_list_menu_factory = NULL;
+static GtkItemFactory *tree_view_menu_factory = NULL;
 
+static GSList *popup_menu_list = NULL;
+
 void
 get_main_menu(GtkWidget ** menubar, GtkAccelGroup ** table) {
 
   grp = gtk_accel_group_new();
 
-  if (initialize)
+  if (initialize) {
+    popup_menu_object = gtk_widget_new(GTK_TYPE_WIDGET, NULL);
     menus_init();
+  }
 
   if (menubar)
     *menubar = factory->widget;
@@ -146,6 +181,18 @@
   if (initialize) {
     initialize = FALSE;
 
+    /* popup */
+
+    packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+    gtk_item_factory_create_items_ac(packet_list_menu_factory, sizeof(packet_list_menu_items)/sizeof(packet_list_menu_items[0]), packet_list_menu_items, NULL, 2);
+    gtk_object_set_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY, packet_list_menu_factory->widget);
+    popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
+
+    tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+    gtk_item_factory_create_items_ac(tree_view_menu_factory, sizeof(tree_view_menu_items)/sizeof(tree_view_menu_items[0]), tree_view_menu_items, NULL, 2);
+    gtk_object_set_data(GTK_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY, packet_list_menu_factory->widget);
+    popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
+    
     factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
     gtk_item_factory_create_items_ac(factory, nmenu_items, menu_items, NULL,2);
     set_menu_sensitivity("/File/Close", FALSE);
@@ -171,19 +218,66 @@
 }
 
 void
+set_menu_sensitivity_meat(GtkItemFactory *ifactory, gchar *path, gint val) {
+	GtkWidget *menu = NULL;
+	
+	if((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL) {
+		gtk_widget_set_sensitive(menu,val);
+	}
+}
+
+void
 set_menu_sensitivity (gchar *path, gint val) {
-  GtkWidget *menu;
+  GSList *menu_list = popup_menu_list;
+  gchar *shortpath = rindex(path, '/');
+
+  set_menu_sensitivity_meat(factory, path, val);
 
-  if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
-    gtk_widget_set_sensitive(menu, val);
+  while (menu_list != NULL) {
+  	set_menu_sensitivity_meat(menu_list->data, shortpath, val);
+	menu_list = g_slist_next(menu_list);
+  }
+  
 }
 
 void
+set_menu_object_data_meat(GtkItemFactory *ifactory, gchar *path, gchar *key, gpointer data)
+{
+	GtkWidget *menu = NULL;
+	
+	if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
+		gtk_object_set_data(GTK_OBJECT(menu), key, data);
+}
+
+void
 set_menu_object_data (gchar *path, gchar *key, gpointer data) {
-  GtkWidget *menu;
+  GSList *menu_list = popup_menu_list;
+  gchar *shortpath = rindex(path, '/');
   
-  if ((menu = gtk_item_factory_get_widget(factory, path)) != NULL)
-    gtk_object_set_data(GTK_OBJECT(menu), key, data);
+  set_menu_object_data_meat(factory, path, key, data);
+
+  while (menu_list != NULL) {
+  	set_menu_object_data_meat(menu_list->data, shortpath, key, data);
+	menu_list = g_slist_next(menu_list);
+  }
 }
 
+void
+popup_menu_handler(GtkWidget *widget, GdkEvent *event)
+{
+	GtkWidget *menu = NULL;
+	GdkEventButton *event_button = NULL;
 
+	if(widget == NULL || event == NULL) {
+		return;
+	}
+	
+	menu = widget;
+	if(event->type == GDK_BUTTON_PRESS) {
+		event_button = (GdkEventButton *) event;
+		
+		if(event_button->button == 3) {
+			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time);
+		}
+	}
+}
Index: gtk/menu.h
===================================================================
RCS file: /cvsroot/ethereal/gtk/menu.h,v
retrieving revision 1.1
diff -u -r1.1 menu.h
--- menu.h	1999/09/01 03:04:23	1.1
+++ menu.h	1999/12/20 21:04:28
@@ -38,7 +38,9 @@
 void set_menu_sensitivity (gchar *, gint);
 void set_menu_object_data (gchar *path, gchar *key, gpointer data);
 void menus_create (GtkMenuEntry *, int);
+void popup_menu_handler(GtkWidget *widget, GdkEvent *event);
 
+GtkWidget           *popup_menu_object;
 
 #ifdef __cplusplus
 }