After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 96637 - Support RTL flipping for menu items
Support RTL flipping for menu items
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
2.1.x
Other other
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks: 76219
 
 
Reported: 2002-10-23 18:24 UTC by Matthias Clasen
Modified: 2011-02-04 16:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
first step - flippability for accel labels (1.29 KB, patch)
2002-10-25 00:03 UTC, Matthias Clasen
none Details | Review
remaining stuff: flippability for menuitem, checkmenuitem, radiomenuitem, imagemenuitem, tearoffmenuitem (8.07 KB, patch)
2002-10-25 21:48 UTC, Matthias Clasen
none Details | Review
flip submenu cascading (1.97 KB, patch)
2002-10-25 23:12 UTC, Matthias Clasen
none Details | Review
cascading again (3.62 KB, patch)
2002-10-26 23:23 UTC, Matthias Clasen
none Details | Review
revised patch (12.05 KB, patch)
2002-10-27 23:08 UTC, Matthias Clasen
none Details | Review
fix for drawing rtl submenu arrows (680 bytes, patch)
2002-11-05 23:11 UTC, Matthias Clasen
none Details | Review
ltr example (2.79 KB, image/png)
2002-11-05 23:12 UTC, Matthias Clasen
  Details
rtl example (2.79 KB, image/png)
2002-11-05 23:13 UTC, Matthias Clasen
  Details

Description Matthias Clasen 2002-10-23 18:24:55 UTC
must move accelerator and submenu indicators to the left, and icons, checks,
toggles, etc to the right in RTL mode.
Comment 1 Owen Taylor 2002-10-23 19:08:10 UTC
Moving all the RTL flipping bugs to the 2.4.0 milestone; in some
cases the changes should be easy to do. (GtkPaned comes to mind)
In those cases, we can move the bugs back to 2.2.0 if patches occur.
Comment 2 Matthias Clasen 2002-10-25 00:03:22 UTC
Created attachment 11818 [details] [review]
first step - flippability for accel labels
Comment 3 Matthias Clasen 2002-10-25 21:48:57 UTC
Created attachment 11835 [details] [review]
remaining stuff: flippability for menuitem, checkmenuitem, radiomenuitem, imagemenuitem,  tearoffmenuitem
Comment 4 Matthias Clasen 2002-10-25 23:12:46 UTC
Created attachment 11838 [details] [review]
flip submenu cascading
Comment 5 Matthias Clasen 2002-10-25 23:24:01 UTC
The last patch does not only change the cascading of submenus, but
also makes first-level submenus right-aligned with the menubar-item
which popped them up in RTL mode. 
This exposes a bug, which can be seen in testgtk with this patch applied:

Enable RTL mode (in "flipping")
Start "Item Factory" example. Select "Preferences". Note that the
submenu doesn't come up properly right-aligned. It is too far to the
right, the difference being approx. the size of the submenu
indicators. This problem occurs only for the Preferences menu and only
on the first mapping. Inserting printfs in
gtk_menu_item_position_menu() confirms that
GTK_WIDGET(menu)->requisition.width is smaller on the first mapping
than on the second mapping of the menu. 

The bug is not specific to the RTL code, it can also be exposed in LTR
mode: Position the "Item Factory" example over the right edge of the
screen, so that only the submenu indicators of the "Preferences" menu
would be offscreen. Then pop the "Preferences" menu up for the first
time. It is partially offscreen, because the calculation to detect
offscreenness is done with the too small requisition.width. On the
second mapping, the menu is moved to the left to bring it completely
on screen, as intended.
Comment 6 Owen Taylor 2002-10-26 21:00:00 UTC
the accel label patch looks good to me.

in gtkimagemenuitem, you have a left-over:

+      g_print ("toggle_size %d width %d\n", GTK_MENU_ITEM
(image_menu_item)->toggle_size, width);

As a general style thing, I might write:

+      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) 
+	x = widget->allocation.width - GTK_CONTAINER
(image_menu_item)->border_width -
+	  widget->style->xthickness - 
+	  GTK_MENU_ITEM (image_menu_item)->toggle_size +
+	  (GTK_MENU_ITEM (image_menu_item)->toggle_size - width) / 2;
+	else
+	  x = GTK_CONTAINER (image_menu_item)->border_width +
+	       widget->style->xthickness +
         (GTK_MENU_ITEM (image_menu_item)->toggle_size - width) / 2;

As something like:

      border = (GTK_CONTAINER (image_menu_item)->border_width +
                widget->style->xthickness + 
                (GTK_MENU_ITEM (image_menu_item)->toggle_size - width)
/ 2;
      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        x = border;
      else
        x = widget->allocation.width - border - GTK_MENU_ITEM
(image_menu_item)->toggle_size;

To make reduce the duplication of code between the two cases.
(I also slightly prefer having the LTR case first.) A slightly
different way of doing this to calculate 'x' for the right-to-left
case and flip it, using the general formula:

 item_x_flipped = overall_x + overall_width - (item_x - overall_x) -
item_width;

 So, you can write:

   x = .....;  /* Calculate LTR position leaving out overall_x */

   if (direction == GTK_TEXT_DIR_LTR)
     item_x = overall_x + x;
   else
     item_x = overall_x + overall_width - x - item_width;

The same as the above really, except s/border/x/, since 
overall_x == 0.

In gtkmenuitem.c, you have a misplaced { in:

+      if (menu_item->submenu && menu_item->show_submenu_indicator) {


The calculation:

+	  if (direction == GTK_TEXT_DIR_RTL) {
+	    arrow_x = x + 1;
+	    arrow_type = GTK_ARROW_LEFT;
+	  }
+	  else {
 	  arrow_x = x + width - 1 - arrow_size + (arrow_size - arrow_extent)
/ 2;
+	    arrow_type = GTK_ARROW_RIGHT;
+	  }

Looks suspicious to me. Shouldn't the centering factor 
(arrow_size - arrow_size_extent) / 2 be in the RTL case as well?
Again, I think it makes sense to treat it as "base calculation
+ flipping".

 arrow_offset = 1 + (arrow_size - arrow_extent) / 2;
 if (direction == GTK_TEXT_DIR_LTR)
   arrow_x = x + width - arrow_offset - arrow_size;
 else
   arrow_x = x + arrow_offset;


In gtktearoffmenuitem.c, the calculation:

+	      if (direction == GTK_TEXT_DIR_RTL) {
+		arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2; 
+		arrow_type = GTK_ARROW_RIGHT;	    
+	      }
+	      else {
 	      arrow_x = ARROW_SIZE / 2;
+		arrow_type = GTK_ARROW_LEFT;
+	      }
 	      x += 2 * ARROW_SIZE;

The x += ARROW_SIZE doesn't look for me for the RTL case.

The RTL-cascade patch looks fine.

Is the bug you are reporting here related to bug 80764? I don't
think so offhand, but it's sort of similar.
Comment 7 Matthias Clasen 2002-10-26 22:06:52 UTC
Yes, looks like it is the same problem as in bug 80764. 
At least I see that the requisition width of the "Preferences" menu
grows between the first and the second mapping because the
accel_string_width of the contained accellabels goes from 0 to 18...

I will append further diagnosis to bug 80764. Thanks for the detailed
patch review, btw. Will provide corrected patches here as soon as the
accel label bug is fixed.
Comment 8 Matthias Clasen 2002-10-26 23:22:38 UTC
What the cascading bug doesn't get right is reacting to changes in the
text direction during the menubar lifetime, since the toplevel menu
items in the menubar set their submenu direction based on the text
direction at creation time. The submenu direction is then inherited
throughout the hierarchy. 

This may not be worth fixing, since text direction is normally constant, 
but a fix turns out to be relatively simple: just re-set the submenu
direction before popping up the submenu for toplevel menu items.
Comment 9 Matthias Clasen 2002-10-26 23:23:28 UTC
Created attachment 11861 [details] [review]
cascading again
Comment 10 Owen Taylor 2002-10-27 00:55:07 UTC
I hesitate to bring it up, but for complete correctness the 
code probably also should reset the menu direction for children
of torn off menus. (if (GTK_IS_MENU (item->parent)) &&
menu->torn_off && !menu->active).

You could at least reproduce this bug in testgtk pretty 
trivially, though I have trouble imagining a real-life
case.
Comment 11 Matthias Clasen 2002-10-27 23:08:00 UTC
Created attachment 11881 [details] [review]
revised patch
Comment 12 Owen Taylor 2002-11-01 23:05:16 UTC
We don't actually reset ->torn_off when popping up a menu
that is torn off, which is why you need the !menu->active
check as well.

I'd really like to see the GtkAccelLabel bug fixed in 
GtkAccelLabel rather than worked around here.
Comment 13 Owen Taylor 2002-11-02 04:15:57 UTC
Hmm, testing it it looks to me like the arrows for RTL menu
items aren't quite positioned right ... the look too far to
the right.
Comment 14 Matthias Clasen 2002-11-05 23:11:08 UTC
I believe this is mostly fixed by the patch below. There is still a
small 1 pixel difference which I can't quite explain, but it looks ok
to me.
Comment 15 Matthias Clasen 2002-11-05 23:11:59 UTC
Created attachment 12075 [details] [review]
fix for drawing rtl submenu arrows
Comment 16 Matthias Clasen 2002-11-05 23:12:40 UTC
Created attachment 12076 [details]
ltr example
Comment 17 Matthias Clasen 2002-11-05 23:13:07 UTC
Created attachment 12077 [details]
rtl example
Comment 18 Matthias Clasen 2002-11-08 22:00:50 UTC
Committed to HEAD now.