OptionMenu questions

Howdy folks. I was playing around with a minor issue with the OptionMenu that annoys the heck out of me, and it raised some questions for me. (Sorry if this is the wrong place to mention this). The issue I was looking at was what happens when an OptionMenu is stretched to the point that it is wider than the menu it will pop open when clicked. This happens, for example, in the Gnome CD player and some RedHat config tools, as well as the file selector in LibEgg. Clearly there are valid reasons for making the optionmenu expand to fit a given space, but just from an aesthetics standpoint, the popup menu should, in my opinion, have a consistent minimum width (that is, it should always extend AT LEAST to the left edge of the indicator arrow). I've kind of worked out a "demo" patch for this problem to give an idea of how this could work, but it is bad. What it does, essentially, is looks at how wide the option menu wants to be, and compares that to how wide the option menu "should be" according to what I just described in the preceding paragraph. There are several cases which ensure that the popup menu appears fully on the screen, and in these cases, the menu is shortened until it can just fit on the screen, and as a last resort, it is popped up in a different location so it fits on the screen. (This is the previous behavior of the widget, the change is simply that when it has the space, the popup menu is as wide as the optionmenu itself minus the indicator arrow). The problem is that I can see two ways to achieve this, and it isn't clear to me which is more correct (if it is even agreed that this is the proper behavior): 1) The patch attached does this by writing directly into the menu's requisition.width field if it has to. Obviously, I don't want to be poking about in another widget's innards, so this is not really a seriously suggested patch. It is attached anyhow to give an idea of how this works. 2) The other way is to use gtk_widget_set_size_request() to do the same thing (in the begining of gtk_option_menu_position(), you reset the menu so that it will report its "natural" request and you can determine its size). The problem with this is that it doesn't make changes take effect immediately, since a resize will only be queued for after the current set of changes (according to my [quite likely very lame] understanding of how this works). Thus, the width of the menu is always lagged a bit in some of the cases. This isn't really the correct behavior, so I clearly didn't favor this solution, but there may be something else along this track. Perhaps the way to do this would be to create a private subclass of GtkMenu in gtkoptionmenu.c, and make its size requests check with the option menu, but this seems too minor for that. On the other hand, this might also allow a few other minor changes to be made to the behavior of the menu for option menus (ie, convert any ImageMenuItems into regular old MenuItems, or prevent the popup menu from squeezing back onto the screen when the option menu is on an edge, etc). I'd be glad to code this up, of course, if it was desired. I just wanted to float this issue and give an idea of how this looks before going through that. Could be that the architecture really won't allow this to come off easily. I just thought I'd bounce it off you guys.
Index: gtkoptionmenu.c
RCS file: /cvs/gnome/gtk+/gtk/gtkoptionmenu.c,v
retrieving revision 1.66
diff -u -r1.66 gtkoptionmenu.c
--- gtkoptionmenu.c	10 Dec 2002 21:39:53 -0000	1.66
+++ gtkoptionmenu.c	30 Dec 2002 09:26:35 -0000
@@ -908,12 +908,15 @@
   GtkWidget *active;
   GtkWidget *child;
   GtkWidget *widget;
+  GtkOptionMenuProps props; 
   GtkRequisition requisition;
   GList *children;
   gint screen_width;
   gint menu_xpos;
   gint menu_ypos;
   gint menu_width;
+  gint required_menu_width;
+  gint indicator_width; 
   g_return_if_fail (GTK_IS_OPTION_MENU (user_data));
@@ -953,11 +956,28 @@
   screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
+  gtk_option_menu_get_props (GTK_OPTION_MENU (widget), &props);
+  indicator_width = props.indicator_size.width + props.indicator_spacing.left + props.indicator_spacing.right; 
   if (menu_xpos < 0)
-    menu_xpos = 0;
+    {
+      required_menu_width = MAX (menu_width, 
+				 widget->allocation.width + menu_xpos - indicator_width); 
+      menu_xpos = 0;
+    }
   else if ((menu_xpos + menu_width) > screen_width)
-    menu_xpos -= ((menu_xpos + menu_width) - screen_width);
+    {
+      required_menu_width = MAX (menu_width,
+				 screen_width - menu_xpos - indicator_width); 
+      menu_xpos -= ((menu_xpos + menu_width) - screen_width);
+    }
+  else
+    required_menu_width = widget->allocation.width - indicator_width; 
+  /* Force the width of the popup menu if it would otherwise be too small. */
+  GTK_WIDGET (menu)->requisition.width = MAX (required_menu_width, 
+					      GTK_WIDGET (menu)->requisition.width);
   *x = menu_xpos;
   *y = menu_ypos;

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