I've done some closer reading:
> /* This contains the point that was clicked to get this menu */
> Point *object_menu_clicked_point;
>
> void
> popup_object_menu(GdkEventButton *bevent, DDisplay *ddisp)
> {
> Diagram *diagram;
> real click_distance;
> Object *obj;
> Point *clickedpoint;
Pointer here. Not initialized.
> GtkMenu *menu = NULL;
> GList *selected_list;
>
> printf("Trying a middle menu\n");
>
> diagram = ddisp->diagram;
> if (diagram->data->selected_count != 1) return;
> selected_list = diagram_get_sorted_selected(diagram);
> /* Have to have exactly one selected object */
> if (selected_list == NULL || g_list_next(selected_list) != NULL) {
> message_error("Selected list is %s while selected_count is %d\n",
> (selected_list?"long":"empty"), diagram->data->selected_count);
> return;
> }
> obj = (Object *)g_list_first(selected_list)->data;
How come you use the selected object, and not the 'closest' to the
point the user clicked?
> if (obj->ops->get_object_menu == NULL)
> return;
> printf("Trying a middle menu for %s object\n", obj->type->name);
> /* Find the nearest object */
No you don't.
> ddisplay_untransform_coords(ddisp,
> (int)bevent->x, (int)bevent->y,
> &clickedpoint->x, &clickedpoint->y);
Writes via the uninitialized pointer clickedpoint.
> /* Possibly react differently at a handle? */
> /* Get its menu, if it has registered any */
> menu = (obj->ops->get_object_menu)(obj, clickedpoint);
> if (menu == NULL) return;
> printf("Found a middle menu for %s object\n", obj->type->name);
> object_menu_clicked_point = clickedpoint;
Stray pointer gets stored.
> /* Pop up the menu */
> popup_shell = ddisp->shell;
> /* FIXME: Is menu->menu the right thing? */
> gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, 0);
> }
>
> this is the menu-creating function:
>
> static GtkMenu *
> polyline_get_object_menu(Object *obj, Point *clickedpoint)
> {
> GtkMenu *menu;
> GtkAccelGroup *accel_group;
> Polyline *polyline = (Polyline *)obj;
>
> if (polyline_item_factory == NULL) {
> accel_group = gtk_accel_group_new ();
> polyline_item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<PolyLine>",
> accel_group);
You can just pass NULL for the accel_group, as we're not interested in
it.
> gtk_item_factory_create_items (polyline_item_factory,
> sizeof(polyline_menu_items)/
> sizeof(GtkItemFactoryEntry),
> polyline_menu_items, NULL);
> }
> menu = GTK_MENU(gtk_item_factory_get_widget(polyline_item_factory, "<PolyLine>"));
> /* Set entries sensitive/selected etc here */
> gtk_widget_set_sensitive(gtk_item_factory_get_widget(polyline_item_factory,
>"<PolyLine>/Add Corner"), 1);
> gtk_widget_set_sensitive(gtk_item_factory_get_widget(polyline_item_factory,
>"<PolyLine>/Delete Corner"), polyline->poly.numpoints > 2);
> return menu;
> }
I've commented some stuff. The mem clobber is serious, but i can't
understand why it grabs focus and won't let go.
/ Alex