gtk_option_menu_set_menu() weirdness




Hi all,

The attached program creates a table with a button and an 
option menu containing a menu with items "X", "Y", and "Z".
It looks roughly like,

    -----------------
    X_______________|
    |               |
    |  [Click me]   |   <-- Button
    |               |
    |  [  X   \/ ]  |   <-- Option menu
    |               |
     ---------------


When I click the button, the callback calls menu_select() which
changes the selected item in the option menu to the next item
using gtk_option_menu_set_history().

But when I click on the right edge of the option menu (right of
where the menu pops up), the popup menu gives the impression
that the selected item is whatever it was at start time, or
whatever I last set it to with the mouse.

For example, after one click, the app looks like this,

    -----------------
    X_______________|
    |               |
    |  [Click me]   |
    |               |
    |  [  Y   \/ ]  |
    |               |
     ---------------

Then after a mouse click on the option menu, the popup looks
like this,

    -----------------
    X_______________|
    |               |
    |  [Click me]   |
    |  [*X]         |
    |  [ Y]   \/ ]  |
    |  [ Z]         |
     ---------------

Dragging the mouse around highlights different items, but
after dragging over another widget it still looks like above.

It works "ok" in that it returns to "Y" if I click outside
or hit ESC, but the appearance is very confusing.

Is this a bug, a feature, a mis-feature, or a programming
error on my part?

$ gtk-config --version
1.2.5

-Jamie
#include <gtk/gtk.h>

static GtkWidget *option_menu;

static char *menu_items[] =
{
  "X",
  "Y",
  "Z",
  NULL
};

static void menu_select()
{
  GtkWidget *menu;
  static int i=0;
  
  i = (i + 1) % 3;

  menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(option_menu));

  gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu), i);
}

static void menu_setup()
{
  GtkWidget *menu;
  GtkWidget *menu_item;
  GSList *group;
  int i;

  group = NULL;
  menu = gtk_menu_new();

  if (gtk_option_menu_get_menu(GTK_OPTION_MENU(option_menu)))
    {
      printf("Deleting menu!\n");
      gtk_option_menu_remove_menu(GTK_OPTION_MENU(option_menu));
    }
  else
    {
      printf("No menu set yet!\n");
    }

  for (i=0; menu_items[i] != NULL; i++)
    {
      menu_item = 
	gtk_radio_menu_item_new_with_label (group, menu_items[i]);
      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
      gtk_menu_append (GTK_MENU (menu), menu_item);
    }
  gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu);
  gtk_widget_show_all(menu);
}

static gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  gtk_main_quit();
  return FALSE;
}

static void on_click (GtkButton *button,
	       gpointer user_data)
{
  menu_select();
}


int main(int argc, char *argv[])
{
  GtkWidget *w;
  GtkWidget *table;
  GtkWidget *button;

  gtk_init (&argc, &argv); 
  
  w = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_window_set_title(GTK_WINDOW(w), "otest");
  gtk_window_set_policy(GTK_WINDOW(w), TRUE, TRUE, TRUE);
  gtk_window_set_wmclass(GTK_WINDOW(w), "otest", "otest");

  gtk_signal_connect (GTK_OBJECT (w), "delete_event",
		      GTK_SIGNAL_FUNC (delete_event),
		      NULL);

  table = gtk_table_new(5,3,TRUE);

  button = gtk_button_new_with_label("Click me");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC (on_click),
		      NULL);

  gtk_table_attach_defaults(GTK_TABLE(table), 
			    button, 1,2, 1,2);

  option_menu = gtk_option_menu_new();
  menu_setup();
  gtk_table_attach_defaults(GTK_TABLE(table), 
			    option_menu, 1,2, 3,4);

  gtk_container_add(GTK_CONTAINER(w),table);
  gtk_widget_show_all(w);
  gtk_main();
  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]