Community
Participate
Working Groups
BiDi bugs in CoolBar/ToolBar. Please see attachment for details.
Created attachment 6071 [details] detailed description
This bug report actually contains 5 individual bug. Normally, we would require 5 independent reports because some we will fix and some will not. This means, strictly speaking that we can never mark this problem report fixed because there will be unfixed portions. Fortunately, there is only one real problem here. If you do not agree, please open PR's for the other 4 "bugs". Bug 1, Bug 2, - WONTFIX The example code is wrong. FH to fix the example code. Bug 3 - ASSIGNED RTL MenuItem does not draw the image in the wrong position. Bug 4, Bug 5, - WONTFIX The example code is wrong. FH to fix the example code. Since Bug 3 is the only thing we should fix, I am renaming the title.
Semion, could help with this ? You can start of looking at MenuItem.wmDrawChild, in this method windows pass in a DRAWITEMSTRUCT structure which has the rect for receiver to draw within. This rect is not in the correct location when RTL flag is used.
Created attachment 6086 [details] Example Note that I avoid the helper APIs 'new Menu (Menu)', 'new Menu (MenuItem)' and 'new Menu (Control)' cause they don't take style bit. When any of these APIs is used the Menu inherit the orientation of the Shell what is not very instinctive and prone to problems.
Created attachment 6098 [details] Menu and MenuItem with proposed changes. I think, we can do something, as minimum, for Win98/ME/2000/XP. Zip contains your demo with some additional changes, Menu.java and MenuItem.java. Note, that your example demonstraits one more problem (isn't bidi-specific): MenuItem with SWT.CASCADE style can't be displayed with both text and image. This problem is solved with proposed changes too.
Semion, could you please help me to understand your code: - Replace the old style MIIM_TYPE by the new ones MIIM_STRING, MIIM_BITMAP, MIIM_FTYPE. Why do you need this ? Is it for fixing images with cascade items or for fixing images on RTL items ? - Set MIIM_BITMAP in createItem. Again, you need that for fixing images with cascade items or for fixing images on RTL items ? - Not using MFT_RIGHTJUSTIFY | MFT_RIGHTORDER, but mirroring the GC in wmDrawChild instead. I believe this is the real fix for the problem with images on RTL items. Is it safe doing this ? - In MenuItem.setText you set info.hbmpItem with HBMMENU_CALLBACK, but mask doesn't have the MIIM_BITMAP flag, it seems wrong. - Always increase MEASUREITEMSTRUCT during wmMeasureChild. The trim added in this method goes around the image, so why do you need this space when there is no image ? It would be better if you had just fix one bug (don't bother with images on Cascade items) and if you had used the code base from HEAD.
Semion, FYI: Windows CE does not support the new style flag. I found a bug in the code, Run the code setting opposite orientation for the Shell and the Menu bar, see what happens.
Created attachment 6144 [details] New versions of Menu and MenuItem This attachment contains new versions of Menu.java and MenuItem.java with proposed changes. In addition two new definitions should be added to OS.java: public static final int MIIM_STRING = 0x40; public static final int MIIM_FTYPE = 0x100; Yes, proposed fix is mirroring the GC in wmDrawChild(). Because we should mirror GC of all items, including such of them, which doesn't have image, we should define all items with MIIM_BITMAP in the fMask and with HBMENU_CALLBACK in the hbmpItem field of MENUITEMINFO. Mirroring shouldn't be done for items of MenuBar, therefore for these items we, as usually, should use MFT_RIGHTJUSTIFY bit ( but not MFT_RIGHTORDER bit, which change direction of all cascade items in the tree of menus). When rtl cascade item belongs to drop-down menu, which is connected with item from menu bar, and when it has text only and this text has the longest length in it's drop-down menu, this item doesn't have space between arrow and text. Using wmMeasureChild() we can increase this distance.
Created attachment 6151 [details] One more version of MenuItem.java We have one more problem with items from MenuBar. Change of MenuBar's orientation doesn't cause corresponding change of text order of it's items. We can solve this problem in wmDrawChild() using SetTextAlign() and TA_RTLREADING flag (TA_RTLREADING = 256).
The code relies on mirroring the GC before drawing and it assumes that the OS will draw after it. It fails cause the OS can draw with the GC before we changed the orientation, or the OS can draw with another GC. There is no guaranties. Using LTR Shell and RTL MenuBar and RTL DropDown Menu, try this scenarios: The first MenuItem in the DropDown Menu is SWT.CHECK or SWT.RADIO, select it, and pop-up the menu again. -> The check mark and the radio mark are drawn before the GC is mirrored and therefore are in the wrong position. ->The second MenuItem in the DropDown Menu is SWT.CHECK or SWT.RADIO, select it, and pop-up the menu again. When the menu first shows up the check mark (or the radio mark) are in the right place, hover the MenuItems with mouse, once you hover the second item it draws again (with selection background), the check mark (or the radio mark) are move to the wrong place. -> The shadows and the positioning of the DropDown Menu are wrong.
I agree. Currently I don't see solution for this problem. We can try to use MFT_OWNERDRAW to receive full control for drawing the menu, but it is quite another principle of work. What do you think about this?
Owner draw will cause too many problems... drawing mnemonics and accelerators are very hard. Two ideas, before calling GC.win32_new() in wmDrawChild (), we can: Add `data.layout = -1;` which will conserve the gc orientation which is good by default (it has the same orientation as the Shell). In case where the Menu bar orientation and the Shell orientation are not the same we will need to change the gc orientation, for that we could add the line: `data.style = parent.style & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT);` instead of `data.layout = -1;`. Still won't work cause the check marks, radio marks, arrow and text alignment can be wrong. That is because we are changing the same gc that the OS will use to draw. The code should save the GC state, change it, draw, and restore the GC state before returning it to the OS. The latest version of my hack looks like: LRESULT wmDrawChild (int wParam, int lParam) { DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT (); OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof); if (image != null) { GCData data = new GCData(); data.device = display; //data.style = parent.style & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT); data.layout = -1; GC gc = GC.win32_new (struct.hDC, data); int layout = -1; if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) { layout = OS.GetLayout (gc.handle); OS.SetLayout (gc.handle, OS.LAYOUT_RTL); } gc.drawImage (image, struct.left, struct.top + 2); if (layout != -1) { OS.SetLayout (gc.handle, layout); } gc.dispose (); } return null; } Still, I'm having some problems with mesaurments and I didn't test pop-up menus.
Probably I missed something. I already tried the similar code in wmDrawChild() and refused from it, because check and radio marks are displayed in this case in the same place, as our images, therefore we don't see them. Do you have this problem too? I don't understand, what you wrote about orientation of MenuBar and how it connected with orientation of drop-down menu. As far as I understand, our problem appears, when orientation of current menu is differ from orientation of Shell...
I've release code in HEAD to initialize GCData.layout with -1. Whitout this the code on HEAD would always align menu item images on the wrong edge. Still, the scenario Menu (with Images) and Shell with different orientation. I'm afraid we can not fix this problem. It looks like OS limitation/bug that we can't work around. Note: In 2.1.2 since the wmDrawChild code doesn't use GC (it uses BitBlit instead) we actually don't need to change any code.
We won't be working around the Windows limitation.
*** Bug 87760 has been marked as a duplicate of this bug. ***
Just to add a comment on this bug, this behavior is also buggy in Vista. I don't know if Vista has also problems on rendering icons for RTL menu items bug its menu items have a place for icons (like office 2003 e.g), which is not used by SWT. SWT reners icons in another place.