- From: "David Santiago" <mrcooger cyberverse com>
- To: gtk-devel-list gnome org
- Subject: OptionMenu questions
- Date: Mon, 30 Dec 2002 02:50:02 -0800
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
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.
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 @@
+ GtkOptionMenuProps props;
+ 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);
+ 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;
] [Thread Prev