Community
Participate
Working Groups
While SWT is superior to AWT in many ways, SWT currently falls short of its counterpart in the realm of automated whitebox GUI testing. We are currently working on extending Abbot, a Java GUI testing framework originally intended for AWT, for use with SWT to allow for whitebox testing of SWT GUIs. To accomplish this, we need the capability to programmatically manipulate SWT Widgets in a manner that mimics the user. To this end, we need to be able to locate ANY Widget in display-coordinates. Currently, only Controls have a getLocation() method that provides this functionality (by calling parent.toDisplay(control.getLocation()). Other specific subclasses of Widget have a getBounds() method- Caret, CoolItem, Decorations, TableItem, ToolItem, and TreeItem- that allow us to find instances of these classes in display coordinates. And Menu has a public handle that allows for a platform-specific means of locating the Menu in display coordinates. This leaves MenuItem, TabItem, TableColumn, and Tracker, at least right now, unfindable. The problem, then, lies in both the non-uniformity of these strategies to obtain something as simple as display coordinates and the lack thereof for Widgets of type MenuItem, TabItem, TableColumn, and Tracker. We would like to request the addition of method(s) that, given an instance of a Widget, would return an org.eclipse.swt.graphics.Rectangle representing the bounding box for the Widget in Display coordinates. And a final note. Methods like getLocation, getBounds, and set/getFocus are only available to particular sub-classes of Widget, but these methods are applicable to ALL (or nearly all) Widget subclasses. It would be worthwhile, then, to include these methods in the abstract class Widget and handle special cases by overriding these methods in Widget sub-classes. I am aware that these operations- particularly set/getFocus- may not be applicable to particular Widget sub-types. In these cases, however, it would be logical to execute the parent's appropriate method instead. For example, we would give focus to the Widget's parent, or return the bounding box for the parent, if it were not possible to do so for a particular Widget sub-type itself.
Check the map API in Display: public Rectangle map (Control from, Control to, Rectangle rectangle) You should call this API to map the coordinates from a Control to the Display, you should also give a rectangle (getBounds) and not a point (getLocation) to do this kind of operation. It's important if you are running on a Mirrored coordinates system (arabic/hebrew). Still, this does not solve all your problems... SN to advise.
Could you please provide getBounds() for all Widget's? Why I ask: In order for an SWT automation tool to programmatically interact with a target, it must be able to 0 use information provided by the coder to identify the target 1 get the size or position of the target 2 generate native events using those coordinates Fortunately * task 0 is done by navigating the graphical hierarchy * task 1 is easy if your target is a Control * there are at least two ways to do task 2 (using abbot.swt.Robot, in http://sourceforge.net/projects/abbot or Sebastian Peleato's API) The problem is that not all targets are Control's, especially if one wishes to automate menu picking/navigation. We have workarounds, but they are platform-specific (which complicates tool building and deployment), underperformant (which degrades the user's experience), and just plain kludgey. Can you please provide getBounds(), or as similar API as possible, for all Widget's, not just Control's? In 3.0?
As a member of the WSAD performance team, I strongly support Tom / Kevin's request. Today we are using XDE Tester, which only supports a "black box" approach. It requires training and finessing to keep the scripts running; the support for Eclipse 3.0 is pending. I believe that Abbot / Costello for SWT would be a better fit for our needs and those who hope to systematically track performance regressions. Background: Gary Karasiuk, Sonia Dimitrov, and myself recently finished some work to integrate our performance plug-in, ptracker, into the Eclipse build. The goal is to supplement the JUnit launcher used today with one that captures key performance metrics with each build. This will allow the Eclipse team to find performance regressions the day after they occur (not weeks!), saving countless hours of post-build detective work. Abbot / Costello is a natural extension of this effort. Today our performance testcases are limited to what can be executed in JUnit. These testcases, while very good at detecting regressions in functionality, only approximate the true user experience. If the underlying support for Abbot is completed, myself and others on our team will provide high-level **real** user scenarios to the Eclipse build team to fill out the incomplete performance regression capability. This obviously won't occur if we are reliant exclusively on XDE Tester as we are today. SWT's use of native widget makes 80% of Abbot's job easy. However, the last 20% that is missing makes its usage klunky, awkward, slow, and unreliable. We would really like to see SWT supported as a first-class citizen among automated testing tools, and Abbot / Costello seems to be the obvious choice.
We have attempted various workarounds to this problem (the lack of getBounds() for non-Control widgets)- for example, making an SWT API call to setSelection (boolean) in a testcase instead of actually generating a mouse-click input event. This, however, is unacceptable, as it makes for testcases that do not accurately reflect a realistic user scenario. We've also tried making approximations of a widget's size and location based on its text/image content, but this incomplete approach is not a final solution either. The lack of getBounds() for MenuItems is particularly debilitating. Currently, the only way to automate MenuItem selection is to do so via accelerators and keystrokes. However as Tom mentioned above, this method cannot consistently work across platforms and applications and is flimsy at best. I'm beginning work on a patch for MenuItem.getBounds(), starting with win32. It appears that wrapping the native win32 method GetMenuItemRect(HWND, HMENU, UINT, LPRECT) should (essentially) provide the functionality we need. And hopefully a similar approach will work with the other supported windowing systems. The patch should allow Abbot to deal with MenuItems in much the same way as it does Controls, and the added consistency in implementation will result in a more reliable and capable testing tool. In particular, testcases will be able to include menu navigation via mouse clicks. This method is certainly more representative of real user interaction than what Abbot's current capabilities allow. HOWEVER, there will still be important non-Control widgets that lack a getBounds () method- TableItem, TreeItem, CoolItem, ToolItem, and Scrollbar- basically any widget that a user can click that does not already provide a getBounds() method.
Disregard the last paragraph of my most previous post- it doesn't reflect the most recent SWT API. The amended list of widgets that lack a getBounds() method should be- MenuItem, TableColumn, Tab, and ToolItem. I'll be working on a patch for all of these in the coming week.
Created attachment 10629 [details] Initial patch for various getBounds() methods On Windows, I've implemented the following: - TableColumn.getBounds() - TabItem.getBounds() - MenuItem.getBounds() The first two have no restrictions; MenuItem.getBounds(), however, currently only works for items in bar menus, as I am only able to obtain the size of a given MenuItem in a cascade or popup menu but not its location. In particular, GetMenuItemRect doesn't appear to work as advertised in the win32 documentation, and I'm not sure where to go from here. Any help with this particular problem would be greatly appreciated. The attached zip file contains fixes bound by "//TODO: Begin patch" and "//TODO: End patch". Changes were made in org.eclipse.swt.internal.win32.OS and org.eclipse.swt.widgets.{MenuItem,TableColumn,TabItem}. I will also be passing along an Abbot-driven JUnit test case that demonstrates the new functionality to Dan Kehn.
Created attachment 10676 [details] MenuItem.getBounds() fix Includes everything in the previous patch(10629), plus a new-and-improved MenuItem.getBounds() for win32 with no restrictions. It now works on items in bar, cascading, and popup style menus.
*** Bug 39184 has been marked as a duplicate of this bug. ***
Can provided Widget-location patches be rolled into SWT 3.0? (Not M9, but 3.0 final.) Why I ask: Automation is important. SWT's failure to provide the ability to locate (and therefore drive) all Widget's presents a competitive disadvantage, given that AWT/Swing allows one to find all its Component's. If SWT (the organization) fails to provide this, automators will need to patch SWT (the code), minimally for menuing. An automation tool has gotta have menuing: there's just too much tooling that's inaccessible without it. (E.g. a friend in another IBM group wants to start testing a GEF-based component, but can't because the component allows a user to interact with its figures only through context menus.) We will eventually need the other non-Control Widget's, but we need menuing now. So I'm wondering, how can we get this into 3.0? Note that * academic summer being upon us, my group has some more resources available, so we can assist with this task. * I'm frankly skeptical regarding the claim made in https://bugs.eclipse.org/bugs/show_bug.cgi?id=39184 that this can't > happen for 3.0 because we are API frozen (unless mountains are moved > with the PMC). for 2 reasons: · This is new API. Since no one's currently using it, how can it break anyone? Feel free to deprecate the API, "label as hazardous," whatever, to protect the innocent. · Is there now, or has there ever been, any positive argument for not implementing getBounds() for {MenuItem, TableItem, TreeItem, CoolItem, ToolItem}? I.e. "we should not implement getBounds() for these classes, because <your positive argument here/>"? I suspect not, but I could be wrong. Note also that we will cheerfully kiss rings, move mountains, etc with the PMC as required--but I frankly don't see that as a valid objection to enabling this API, which folks need ... given that an (admittedly partial) implementation is being handed to SWT. So ... how best to get this into 3.0 final?
*** Bug 48341 has been marked as a duplicate of this bug. ***
Created attachment 11493 [details] SWT patch for MenuItem.getBounds() that returns an empty rectangle for invisible items
Created attachment 11498 [details] Test case showing getBounds() for visible and nonvisible menu items
The patch I just posted (SWT patch for MenuItem.getBounds() that returns an empty rectangle for invisible items) is the same as the earlier patch that Kevin wrote, except for an update to MenuItem.getBounds() that causes it to return an empty rectangle instead of garbage in the case when the menu item is not visible. This is done by checking the return value of GetMenuItemRect, which indicates whether menu item bounds were able to be calculated. getBounds() returns coordinates that are relative to the client area of the Decorations that is the parent of the Menu that the MenuItem belongs to. This means that getBounds() can return a rectangle that has negative coordinates. This is seen on Windows: the y-coordinate returned will be negative for menu items on the menu bar since these items lie above the client area. This does not pose a problem, however, since these relative coordinates can easily be turned into screen coordinates through Control.toDisplay(). Therefore in all cases that we have tested this patch returns correct bounds in a manner that is consistent with getBounds() on other widgets that implement getBounds(). I have also posted a test case that dynamically displays the result of getBounds for several MenuItems. In running the test it is possible to see how the bounding rectangle changes from empty to nonempty as menu items are revealed and hidden.
I have been thinking more about MenuItem.getBounds() and I'm coming to the conclusion that we shouldn't implement it (instead we should add a new API that returns widget bounds in Display coordinates). The problem is that on the Macintosh, the menu bar is not in the shell. We can fake this but it won't match the operating system and will have the amazing property that the coordinates will be wrong when the shell is moved. This will happen because when the shell is moved but on the Macintosh, the menu bar stays in the same location instead of moving with the shell like the other platforms. I'm stuck on an API name that means "get the bounds in the display coordinate system". At any rate, the API would be exactly what you need, no coordinate mapping.
Re: Comment #14 Under the Monty Python category, "And now for something completely different..." I believe you're correct Steve. Thinking about it a bit further, two viable approaches come to mind: (a) a new method "getBoundsRoot" (borrowed from similar name in VA/ST, where "root" means screen) as you suggest, or (b) an adapter. The advantage of (b) is that it gets SWT out of the loop entirely, since any framework could provide a set of adapters to the APIs we desire. One method in Widget does it all: public Object getAdapter(Class adapter) { return Platform.getAdapterManager(). getAdapter(this, adapter); // note Platform reference... see PS below } Now that core implements the extension point "org.eclipse.core.runtime.adapters" (it's new and yes, I've tested this in other code and it works as advertised), this is a cost-free alternative from a performance perspective (i.e., before there was no means of registering an adapter except through code, forcing your plug-in's activation). Then Abbot for SWT can handle this little problem on its own in a nice, clean, architected way. If you want to move it later into the SWT layer, great, but there's certainly no urgent need. Since this extension point is relatively new, I'll provide an example of what it would look like in the Abbot4SWT implementation: <extension point="org.eclipse.core.runtime.adapters"> <factory adaptableType="org.eclipse.swt.widgets.Widget" class="org.abbot4swt.WidgetAdapterFactory"> <adapter type="org.abbot4swt.WidgetCoordinateMapper"/> </factory> </extension> The Abbot for SWT folks provide WidgetCoordinateMapper and WidgetAdapterFactory. If there are exception cases (e.g., MenuItem), they either (a) handle it in their WidgetCoordinateMapper with instanceof, or (b) provide a widget-specific adapter (e.g., MenuItemCoordinateMapper). It also opens the door to future adaptation should we discover "SWT shortcomings" later. So how about it, one little method? Tempted? :-) PS: Of course, one gotcha of this approach is the reference to Platform... which presupposes the Eclipse platform runtime is present. That would mean either reflection (returning null if not found) or a fragment. Not perfect, but extensible and gets SWT out of the discussion, now and in the future.
Steve Northover 2004-06-03 09:43 ------- > I have been thinking more about MenuItem.getBounds() and I'm coming > to the conclusion that we shouldn't implement it (instead we should > add a new API that returns widget bounds in Display coordinates). That would be great! I continue to believe that API should be available to * get the bounds of any Widget, just as one can get the bounds of any JComponent. * return consistent co-ordinates for any Widget It's the inconsistency of the present situation Thomas L Roche/Raleigh/IBM@IBMUS 05/28/2004 08:38 PM >> Widget child has getBounds()? >> ------------ ---------------- >> Caret yes, >> parent == null ? relative to display : relative to parent >> Control yes, >> parent == null ? relative to display : relative to parent >> DragSource no, but has getControl() >> DropTarget no, but has getControl() >> Item no >> Menu no, we workaround with getParent().getBounds() >> ScrollBar yes, no javadoc but looks relative to its parent >> Tracker no, but has computeBounds() >> Tray no that most annoys. > The problem is that on the Macintosh, the menu bar is not in the > shell. We can fake this but it won't match the operating system and > will have the amazing property that the coordinates will be wrong > when the shell is moved. This will happen because when the shell is > moved but on the Macintosh, the menu bar stays in the same location > instead of moving with the shell like the other platforms. I believe we can live with this. We have never asked for completeness on all platforms (much less API contracts engraved on tablets)--we understand that some platforms will do things differently. However it is difficult to imagine a platform that did not know the bounds of a thing it was drawing, hence providing bounds-getting API (by whatever name) on Widget makes sense. Dan Kehn 2004-06-03 11:28 ------- > Thinking about it a bit further, two viable approaches come to mind: > (a) a new method "getBoundsRoot" (borrowed from similar name in > VA/ST, where "root" means screen) as you suggest, or (b) an adapter. or (c) both. > The advantage of (b) is that it gets SWT out of the loop entirely, > since any framework could provide a set of adapters to the APIs we > desire. True, but this is a case where the existing SWT API is noticeably fragmented. (c) is best, but (a) is preferable to (b). > PS: Of course, one gotcha of this approach is the reference to > Platform... which presupposes the Eclipse platform runtime is > present. Which is gonna hose testing standalone (non-platform-resident) SWT UIs, no? (b) alone is likely to be insufficient.
Along the same line of implementing getBounds() in various widgets, there are other widgets that implement getBounds() in ways that are less than ideal for automated testing. One of these is TableItem.getBounds(int). This returns a bounding box for the entire item, which for purposes of consistency is probably what should happen. However, selecting an item by clicking on it can only be done by clicking on the table item's text or image. There is no way to get the bounds of the area that can be clicked (presumably the union of the image and text bounds). Are there issues that would make providing this in the API (something like TableItem.getClickableBounds(int)) undesirable? The only workaround that I can foresee for testing is to check the style of the column the text is in and give a default location to click on based on whether it is left, right, or center.
Some platforms allow you to click anywhere on the same line. In general, it's unspecified where you click and with which button.
Steve N., Is there a chance to make progress on this for test tool enablement in 3.0.1? Could you set the target milestone for 3.0.1 or 3.1 as appropriate?
I will mark it when I we have finished assessing the rest of the items.
Steven Wasleski 2004-07-20 14:32 ------- > Could you set the target milestone for 3.0.1 or 3.1 as appropriate? Extra points for 3.0.1! Patching is a drag :-(
This item is still under investigation and will not be added to 3.0.1.
Steven Wasleski 2004-07-20 14:32 ------- >> Could you set the target milestone for 3.0.1 or 3.1 as appropriate? Veronika Irvine 2004-08-25 12:16 ------- > This item is still under investigation and will not be added to > 3.0.1. Could you set the target milestone?
I committed a description of our current patches to the abbot.swt documentation http://cvs.sourceforge.net/viewcvs.py/*checkout*/abbot/abbot.swt/doc/swt/patchingSWT.txt?rev=1.7 Same content is available in slightly different form from http://sourceforge.net/mailarchive/message.php?msg_id=9665074
Thanks. I was actually working on the menu part of this last week but could find no way for the Mac to give back the coordinates of items in the menu bar. It seems that owner draw isn't honoured for Mac menu bars. I tried reaching and getting the MenuBarHandle and looking at the "lastRight" and "menuLeft" fields of the substructures. The documentation says that they aren't when SetRootMenu() is used but I was desparate. I tried every kEventMenu that there was including the amazing kEventMenuGetFrameBounds but this is only called when the user has clicked on a menu bar item. How do automated testing applications move the mouse into the Mac menu bar and hittest the items there? I googled for CGPostMouseEvent() hoping to find example code that did this. Even MenuSelect(), the Mac call that runs the menu bar for the user takes a mouse location. Andre?
If it turns out to be impossible to get the actual bounds for a component, you may have to rely on programmatically activating the component given a proper specification of the final target. This unfortunately leaves out actual display operation of the UI component, which sometimes needs to be tested, but probably the more common case is needing to be able to activate a given menu item. Mac OSX uses AWT components as proxies for the equivalent Swing menu bits when the useScreenMenuBar property is set (which it should be for any OSX java app). The AWT menu items provide no location information (actually rendering the location information of the original Swing components invalid), so they have to be driven programmatically. Unfortunately, I don't know enough about native Mac OS programming to indicate whether the location info is available or not...
Hi Tom, I checked out your patches. It seems to me that none of them need to be in SWT classes. For example, consider the hypothetical method SWT_PATCH.TabItem_getBounds(): public Rectangle TabItem_getBounds(TabFolder parent){ int index = parent.indexOf(this); if (index == -1) return new Rectangle (0, 0, 0, 0); RECT rect = new RECT(); OS.SendMessage( parent.handle, OS.HDM_FIRST + 7 /*OS.TCM_GETITEMRECT*/, index, rect); int width = rect.right - rect.left; int height = rect.bottom - rect.top; return new Rectangle(rect.left,rect.top,width,height); } The advantage of this is that you don't need to patch SWT with your changes and the work needed to port them to other platforms is isolated in one class. The disadvantage is that it is ugly as hell. Hopefully we can implement what you need and the issue becomes moot.
Comments From steve_northover@ca.ibm.com 2004-11-23 10:52 ------- > It seems to me that [none of the abbot.swt patches] need to be in > SWT classes. For example, consider the hypothetical method > SWT_PATCH.TabItem_getBounds(): > public Rectangle TabItem_getBounds(TabFolder parent){ > int index = parent.indexOf(this); > if (index == -1) return new Rectangle (0, 0, 0, 0); > RECT rect = new RECT(); > OS.SendMessage( parent.handle, > OS.HDM_FIRST + 7 /*OS.TCM_GETITEMRECT*/, > index, > rect); > int width = rect.right - rect.left; > int height = rect.bottom - rect.top; > return new Rectangle(rect.left,rect.top,width,height); > } > The advantage of this is that you don't need to patch SWT with your > changes which would be nice, but ... > and the work needed to port them to other platforms is isolated in > one class. ... that keeps the platform port effort isolated onto the shoulders of our zero-FTE-headcount OSS project. Would it not be so much more securely borne by you SWT professionals ?-) After all, the Sun folks don't make us support AWT/Swing API ... Plus, it's s/one class/one class per patched widget/, and rewriting the *Finder and *Tester classes that use them, but those are minor concerns relative to maintaining the proper (IMHO, YMMV) separation of concerns/ effort. > Hopefully we can implement what you need and the issue becomes moot. That's what _I'm_ hoping :-)
Given that you are forced into patching, why not patch in the most optimal way? Put all the work arounds in a single (ugly) class that is outside of the library rather than adding them as methods to the classes where they belong. That way, no one changes anything and odds are good that your code will continue to work when the next release of the library ships. There are more good reasons for this. Suppose that when the methods are added, they return something different or use a different coordinate system. You can isolate those changes in the ugly class. Also, suppose that when the bug is fixed or the feature implemented, someone applies your patches over the fix by mistake. That seems wrong. You should be testing the fixed code, not the patch. Imagine that the bug never gets fixed. You are no worse off and nobody needs to patch anything. This just seems like good software engineering to me.
Additional Comment #27 From Steve Northover 2004-11-23 10:52 ------- >>> consider the hypothetical method SWT_PATCH.TabItem_getBounds(): >>> public Rectangle TabItem_getBounds(TabFolder parent){ >>> int index = parent.indexOf(this); >>> if (index == -1) return new Rectangle (0, 0, 0, 0); >>> RECT rect = new RECT(); >>> OS.SendMessage( parent.handle, >>> OS.HDM_FIRST + 7 /*OS.TCM_GETITEMRECT*/, >>> index, >>> rect); >>> int width = rect.right - rect.left; >>> int height = rect.bottom - rect.top; >>> return new Rectangle(rect.left,rect.top,width,height); >>> } >>> The advantage of this is that you don't need to patch SWT with >>> your changes Additional Comment #28 From Tom Roche 2004-11-23 12:28 ------- >> which would be nice, but ... > and the work needed to port them to other platforms is isolated in > one class. >> ... that keeps the platform port effort isolated onto the shoulders >> of our zero-FTE-headcount OSS project. Would it not be so much more >> securely borne by you SWT professionals ?-) After all, the Sun >> folks don't make us support AWT/Swing API ... Comments From steve_northover@ca.ibm.com 2004-11-23 12:58 (rearranged) > Given that you are forced into patching, why not patch in the most > optimal way? Your rhetorical question is correct (not so sure about this sentence, though :-). But I keep wondering {why I am, how long I will continue to be} forced into patching this. > Put all the work arounds in a single (ugly) class that is outside of > the library rather than adding them as methods to the classes where > they belong. OK, in order to patch this way, what's the best locus for that class? IIUC the patches are minimally platform-dependent, and maximally SWT-version dependent. Remember, I'm trying to isolate abbot.swt (and abbot.swt.gef, etc) users from "raw" SWT--how best to isolate abbot.swt.* from these dependencies? A separate plugin? > That way, no one changes anything and odds are good that your code > will continue to work when the next release of the library ships. > There are more good reasons for this. Suppose that when the methods > are added, they return something different or use a different > coordinate system. You can isolate those changes in the ugly class. Yes, I understand the goodness of Adapter and Decorator ... > Also, suppose that when the bug is fixed or the feature implemented, > someone applies your patches over the fix by mistake. That seems > wrong. Oh, it will be--once you fix SWT, I'm gonna pull the patches off SourceForge so fast the servers will spin :-) > This just seems like good software engineering to me. ... and work for me. FWIW I'd much rather be working on enabling users to write (and hopefully TDD) SWT tests, and getting more coverage for my own tests, than adapting SWT to work with j.a.Robot as AWT does already. That being said, if it'll save me from patching again, I'll do it. Note that my assumption was that, having patched once, the concept would be proven, and I wouldn't hafta patch again ...
Ok, I give up. I was trying to help you in case we don't get to this for 3.1. There is an art to ugly things. If you can't see it, then you never will.
Created attachment 16239 [details] swt_patch3.zip for eclipse 3.1.M3 This is an EXACT port of the changes made to swt-3.0.1 in swt-3.1.M3. Having this, or a similar fix, in the eclipse 3.1 line would be VERY helpful. Thank you to everyone who has already done all the work on this issue. If you download this patch, please, post a note showing your interest in the fix.
I'm still stuck on the Mac. If there is no possible way to get the bounds of a menu item in a Mac menu bar, then MenuItem.getBounds() can never be SWT API. Andre? Where are you?
<< If there is no possible way to get the bounds of a menu item in a Mac menu bar, then MenuItem.getBounds() can never be SWT API. >> It's not unprecedented that GUI whitebox testers have platform-specific limitations. So although it's not ideal, you could throw UnsupportedOperationException.
The thinking is as follows: There are automated GUI testing tools on the Mac. I can't believe that they don't test menus in the menu bar. What do they do? Whatever they do, we should do the same thing rather than offering API that can't be implemented. I'm hoping that there's something I'm missing and that we will be able to make MenuItem.getBounds() work on a Mac.
A quick search on developer.apple.com shows that the MacOS has native calls to determine the bounds of a menu item. The comments I made previously about the bounds being unavailable applies only to the AWT menus providing no API to determine their location (this applies to *all* platforms). When OSX uses AWT menus as proxies for Swing menus, the Swing items' bounds information becomes invalid.
Timothy, can you post the URL to the Mac native calls?
Sorry Steve, I forgot about this PR after some unsuccessful investigation. I'll spend a "Support Incident" with ADC if nothing useful shows up until tomorrow.
I couldn't find any API to calculate the bounds of a menu item directly, but I think it should be possibIe to use the menu definition function for this. I haven't tried this, but you could send a "kMenuCalcItemMsg" to the menuProc where you pass in the menuItem. The parameter menuRect will contain the item bounds on return.
Another (ugly) approach could be probing: you could generate screen coordinates that run from the left to the right screen bound and an increment of about 10 with a vertical position of menuBar.height/2 and map these coordinates to menu items with available API.
I already had a go at probing (yetch) and failed. It seems that the only time you can ask this information is when a drop down menu is pulled down. Then, inside the "cascade callback", you can get the bounds of the item that was selected. This (of course), is too late. I have workspace full of unreleased hack that I am sitting on that I can make available for you to try, Do you know how the menu definition function differs from carbon events? I saw kMenuCalcItemMsg but thought that because we didn't use a custom menu definition that it didn't apply. Also I had no clue how to send a fake menu definition function event like kMenuCalcItemMsg. Also it seemed that this event applied to MenuRefs, not MenuBarHandles (or the various things inside them that represent the menu bar). Please spend a support incident with ADC on this as it is holding up the API.
OK, will do. (Shouldn't we create a new bug report for this? Whenever we add a new comment, most likely we are spamming a lot of people probably not too interested in the Mac...)
I don't think so. If people are uninterested in the progress on this bug report, they can remove themselves.
The trick is to use the Accessibility API. After some hacking I came up with the following piece of code which does what you are looking for (I passed in the SWT menubar handle): void dumpMenubarItemBounds(MenuRef menu) { AXUIElementRef ref= AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)menu, (UInt64)0); if (ref != NULL) { int i= 0; CFArrayRef children; fprintf(stderr, "menubar item bounds:\n"); AXUIElementCopyAttributeValue(ref, kAXChildrenAttribute, (CFTypeRef*) &children); CFIndex count= CFArrayGetCount(children); for (i= 0; i < count; i++) { CFTypeRef valueRef; CGPoint position; CGSize size; CFStringRef title; AXUIElementRef menuItem= (AXUIElementRef) CFArrayGetValueAtIndex(children, i); AXUIElementCopyAttributeValue(menuItem, kAXTitleAttribute, (CFTypeRef*) &title); const char *t= CFStringGetCStringPtr(title, kCFStringEncodingMacRoman); AXUIElementCopyAttributeValue(menuItem, kAXPositionAttribute, &valueRef); AXValueGetValue(valueRef, kAXValueCGPointType, &position); AXUIElementCopyAttributeValue(menuItem, kAXSizeAttribute, &valueRef); AXValueGetValue(valueRef, kAXValueCGSizeType, &size); fprintf(stderr, " %d %s: x:%d y:%d w:%d h:%d\n", i, t, (int)position.x, (int)position.y, (int)size.width, (int)size.height); CFRelease(valueRef); CFRelease(title); } CFRelease(children); CFRelease(ref); } }
Thanks!
Andre, I added the following code in Menu.java (plus the natives to OS): public Rectangle[] getItemBounds () { if ((style & SWT.BAR) != 0) return null; int menuRef = handle; int ref = OS.AXUIElementCreateWithHIObjectAndIdentifier (menuRef, (long)0); if (ref != 0) { int [] children = new int [1]; System.out.println("XAERROR: " + OS.AXUIElementCopyAttributeValue (ref, OS.kAXChildrenAttribute (), children)); int count = OS.CFArrayGetCount (children [0]); Rectangle [] result = new Rectangle [count]; int [] valueRef = new int [1]; CGPoint position = new CGPoint (); CGSize size = new CGSize (); for (int i = 0; i < count; i++) { int menuItem = OS.CFArrayGetValueAtIndex (children [0], i); OS.AXUIElementCopyAttributeValue (menuItem, OS.kAXPositionAttribute(), valueRef); OS.AXValueGetValue (valueRef [0], OS.kAXValueCGPointType, position); OS.CFRelease (valueRef [0]); OS.AXUIElementCopyAttributeValue (menuItem, OS.kAXSizeAttribute(), valueRef); OS.AXValueGetValue (valueRef [0], OS.kAXValueCGSizeType, size); OS.CFRelease (valueRef [0]); result [i] = new Rectangle ((int)position.x, (int)position.y, (int)size.width, (int)size.height); } return result; } return null; } But when I execute it I get an AXERROR equals to -25211 (kAXErrorAPIDisabled), do you know how to fix this ?
Interesting, for security reasons Apple disables the Accessibility API if the user hasen't enabled the "Enable access for assistive devices" option in System Preferences (I always have this option on to see focus borders everywhere). You can turn it on via the "System Preferences > Universal Access > Enable access for assistive devices" Sorry, I didn't know that and had to Google for it...
it looks like we can't use this API then :-(
Why? The API is for whitebox testing. I don't see a problem to require that the option is turned on.
Some call it a "platform reality" :-)
Felipe Heidrich 2004-12-03 16:20 ------- >>>>> Andre, I added [Menu.getItemBounds()] (plus the natives to OS): <snip> >>>>> But when I execute it I get an AXERROR equals to -25211 >>>>> (kAXErrorAPIDisabled), do you know how to fix this ? Andre Weinand 2004-12-03 17:00 ------- >>>> Interesting, for security reasons Apple disables the >>>> Accessibility API if the user hasen't enabled the "Enable access >>>> for assistive devices" option in System Preferences (I always >>>> have this option on to see focus borders everywhere). You can >>>> turn it on via the "System Preferences > Universal Access > >>>> Enable access for assistive devices" >>>> Sorry, I didn't know that and had to Google for it... Felipe Heidrich 2004-12-03 17:14 ------- >>> it looks like we can't use this API then :-( Andre Weinand 2004-12-03 17:27 ------- >> Why? The API is for whitebox testing. >> I don't see a problem to require that the option is turned on. Andre Weinand 2004-12-03 17:40 ------- > Some call it a "platform reality" :-) Agreed: it's realistic to assume the user will need to do other things to "instrument," or enable testability for, any given platform @ runtime. As long as it compiles, and doesn't break other function, I don't see a problem with, e.g., javadoc'ing or FAQ'ing similar requirements--"call at your own risk." It Would Be Nice if s/he didn't hafta, but that may be the price to pay for automation.
Display.setCursorLocation(point) does nothing on some platforms, so maybe this method could nothing, or return an empty rectangle when accessibility is disabled.
An empty rectangle isn't an option when the option is disabled. How about trying Apple again for another approach?
Yes, I've contacted DTS and for security reasons there is no other approach.
The Mac has been around since 1984. It is 2004 (almost 2005). HIObject is new to OS 10.x. In all those years nobody has written a GUI testing tool that pulls down a menu bar menu and selects an item? Andre, can you please ask again how GUI testing tools perform this action? The issue here is that having an API that fails and requires the user to change something on the control panel is not a good solution. Thanks.
Steve, so what is the issue now? - getting API so that SWT can implement Menubaritem.getBounds(), or - driving the Mac UI from another process? Whether GUI testing tools existed before MacOS X (1984-2001) doesn't really matter since they could easily patch the OS and wouldn't run anyway on MacOS X.
The first hope is that we could get API to implement MenuItem.getBounds() that doesn't require the user to set something in the control panel. If that can't be done, then the next thing is to investigate how this kind of action is normally done on the Mac. Assuming we found something, we would then consider portable SWT API that exposed this capability (we would need to ensure that it could be implemented on the other platforms). It's not great, be we'd be portable and could move on. Again, my first choice would be MenuItem.getBounds(). It's very frustrating because I have an implementation for everything but the menu bar.
Comment #55 From Steve Northover 2004-12-06 10:49 ------- >>> In all those years nobody has written a GUI testing tool that pulls >>> down a menu bar menu and selects an item? Comment #56 From Andre Weinand 2004-12-06 11:15 ------- >> Whether GUI testing tools existed before MacOS X (1984-2001) doesn't >> really matter True. How far back do we hafta support? Note http://www.apple.com/applescript/uiscripting/ > Mac OS X v10.3 includes support for the control of the computer's > graphic user interface via AppleScript. > Graphic user interface control is performed by an updated version of > the System Events application. By addressing the System Events > application, AppleScript scripts can select menu items, push > buttons, enter text into text fields, and generally control the > interfaces of most non-Classic applications. > The following pages detail the process of enabling and using the GUI > Scripting architecture.
... but, as Andre mentioned http://www.apple.com/applescript/uiscripting/01.html > The GUI Scripting architecture is based upon the Mac OS X > accessibility frameworks that provide alternative methods of > querying and controlling the interfaces of the OS and applications. > By default, the accessibility frameworks are disabled. An > administrative user can enable them by clicking the checkbox labeled > "Enable access for assistive devices" in the Universal Access System > Preference pane and entering their password in the [subsequent] > authentication dialog. > Once the accessibility frameworks have been activated, AppleScript > can be used to query and control the user interface of most > applications. Scripted actions are performed by addressing the > System Events application which has a special script suite for > communicating with the GUI Scripting architecture. Is there API to query or set the Universal Access System?
Comment #55 From Steve Northover 2004-12-06 10:49 ------- >>> In all those years nobody has written a GUI testing tool that pulls >>> down a menu bar menu and selects an item? Comment #56 From Andre Weinand 2004-12-06 11:15 ------- >> Whether GUI testing tools existed before MacOS X (1984-2001) doesn't >> really matter >> True. How far back do we hafta support? Note The Mac menu bar is not new to 10.x. Can anyone tell me what API pre-10.x GUI testing applications did? Mac API is backwards compatible.
Re: comment #55: I've sent your request to DTS. Re: comment #59: > Is there API to query or set the Universal Access System? Yes, and the example application http://developer.apple.com/samplecode/UIElementInspector/UIElementInspector.html uses it to make the user enable the Universal Access option. Re: comment #60: > Mac API is backwards compatible. Yes, if you run your pre-Carbon apps in Classic mode (MacOS 9 running inside MacOS X). Native MacOS X apps must only use Carbon which is a smaller subset of the original Mac Toolbox.
comment #59: >> Is there API to query or set the Universal Access System? comment #61 > Yes, and the example application > http://developer.apple.com/samplecode/UIElementInspector/UIElementInspector.html > uses it to make the user enable the Universal Access option. <Do I need XCode to read UIElementInspector/UIElementInspector.app/Contents/MacOS/UIElementInspector ?/> Hopefully "DTS" will come up with a cleaner solution, but {if not, for the nonce} why not support Carbon (do we even support Classic or Cocoa?) like if (Universal Access not set) { if (user not administrative) throw SWTException // ERROR_USER_LACKS_PERMISSION set it } return bounds ?
Re comment #62: You can find the source in the files ending in .h and .m UIElementInspector/UIElementInspector.app/Contents/MacOS/UIElementInspector is the executable. You don't want to read it :-)
One more thing to patch: could SWT make ScrollBar.getBounds() public? I notice, thanks to http://sourceforge.net/tracker/index.php?func=detail&aid=1080952&group_id=50939&atid=461490 that if I do export WS="win32" export PLATFORM="x86" export DEVSPACE="/d/eclipse/devspaces/scratch" # outside of eclipse? (automate this) copy the patchfiles here export PATCHESPATH="$DEVSPACE/patchfiles" export INPUT="eclipse-SDK-3.1M3-$WS.zip" export ZIPHOME="ftp://fullmoon.rtp.raleigh.ibm.com/S-3.1M3-200411050810/$INPUT" export ZIPSPACE="/d/eclipse/zips" export ZIPVER="3.1.0" export PROJECTPATH="$DEVSPACE/org.eclipse.swt" # !forget to backslash underscores between vars! export SOURCEZIP="eclipse/plugins/org.eclipse.platform.source.$WS.$WS.$PLATFORM\_$ZIPVER/src/org.eclipse.swt.$WS\_$ZIPVER/ws/$WS/swtsrc.zip" export ZIPFILES="$SOURCEZIP \ eclipse/plugins/org.eclipse.swt.$WS\_$ZIPVER/os/$WS/$PLATFORM/swt-*.dll \ eclipse/plugins/org.eclipse.swt_$ZIPVER/plugin.properties \ eclipse/plugins/org.eclipse.swt_$ZIPVER/META-INF/MANIFEST.MF \ eclipse/plugins/org.eclipse.swt_$ZIPVER/plugin.xml \ eclipse/plugins/org.eclipse.swt_$ZIPVER/about.html" wget -O $ZIPSPACE/$INPUT $ZIPHOME cd $DEVSPACE mkdir -p $PROJECTPATH # clean this up! e.g. should move to META-INF/MANIFEST.MF unzip -j $ZIPSPACE/$INPUT $ZIPFILES -d $PROJECTPATH mkdir -p $PROJECTPATH/src unzip $PROJECTPATH/swtsrc.zip -d $PROJECTPATH/src find $PROJECTPATH/src -type f -name '*.java' | \ xargs fgrep -ne 'Rectangle getBounds' | \ fgrep -e '{' | fgrep -v 'public' I get only one line output: > /d/eclipse/devspaces/scratch/org.eclipse.swt/src/org/eclipse/swt/widgets/ScrollBar.java:202:Rectangle getBounds () { Dunno why it should be singled out.
This work won't make it into M4. We are waiting on Apple.
Still waiting on Apple.
Tom, how does the scrollbar bounds help you? There are still magic regions on a scrollbar which don't have API. Have you tried using the client area API? The sides with the larger amount of insets would contain a scrollbar probably.
Comment #67 From Randy Hudson 2005-01-10 17:35 ------- >> Tom, how does the scrollbar bounds help you? Umm ... in order to automate moving a scrollbar we need to know where to tell java.awt.Robot to mouseDown. (I'm suspecting I don't fully understand the question.) >> There are still magic regions on a scrollbar which don't have API. See future FRs :-) Note that I'm only interested in automating and testing common behaviors: something very WS-specific might require native automation. >> Have you tried using the client area API? I'm not sure what you mean: could you show p/code? >> The sides with the larger amount of insets would contain a >> scrollbar probably. In any case, while there may be a workaround in this specific case, Widget.getBounds() is still greatly to be desired. Not only does it greatly simplify simple automation code (I can let the runtime call the appropriate method), but it facilitates higher-level abstractions, which makes it easier for coders to write automated test cases for their targets (which is what my effort is all about). E.g. Abbot has ComponentLocation, which ComponentLocation javadoc > Provides encapsulation of a visible Component-relative location. > Hides the location specifics so that ComponentTester primitives > (actionClick, actionShowPopup, etc) may be directed to specific > elements of substructure on a Component (list rows, tree paths, > table cells, substructure values, etc). with subclasses JListLocation, JTreeLocation, JTableLocation, JTabbedPaneLocation, etc. This relies at base on Component.getBounds(). AFAICS I will need Widget.getBounds() to provide WidgetLocation and subclasses, so that folks can more easily/quickly write tests on JFace thingies. (So far we've been able to automate WDE without WidgetLocation, but I dunno what diabolical graphics those devious GEF folks might devise in future :-)
What I meant was that once you have the scrollbar's bounds, you still have no idea where the down up button are, the thumb, or the areas in between. These areas might depend on the WS skin or certain preferences (e.g. Mac OS). See Scrollable.computeTrim(int,int,int,int) for a possible workaround to obtaining the scrollbar's bounds.
Comment #65 From Steve Northover 2004-12-10 18:06 ------- >> This work won't make it into M4. We are waiting on Apple. Comment #66 From Steve Northover 2005-01-10 17:10 ------- > Still waiting on Apple. While we're waiting, could you make what functionality you have available for use? Abbot has win32 users and folks who are interested in using it with GTK and winCE. We would much rather use your release-quality win32 getBounds()'s than our hacks, and would like to enable folks on non-win32 platforms to make progress. In return, we would provide real-world feedback on their use.
I won't release API that can't be implemented on all platforms. I am working with Apple on another solution but they are slow.
I don't really understand the rationale here Steve N. M4 is a milestone build, and if some obscure feature like this one isn't available for all platforms I don't see the problem. If I remember correctly, the whole Browser widget didn't get released on all platforms at the same time either in 3.0 milestones. The Browser API changed a lot between Milestones as well; its not like it needs to be stabile at this point. And there are even APIs that doesn't work on all platforms in GA builds. Why is this obscure UI-testing-tool feature so different? If Apple responds in M5 or M6 thats great, but are you saying we can never support this (from SWT, I agree there are workarounds) if we cannot have it on OSX and Apple tells us how? I guess my question is why you are so afraid to put it in now? Milestones APIs have changed in the past.. Afraid it cannot ever be supported on all [major] platforms? That the API will radically change when you get info from Apple? Well, just my .0002$
I don't want to put out temporary API that I may need to retract later.
Any word from Apple?
Sigh. Hopefully something at EclipseCon.
Hi Steve, any news on Apple's side?
I talked to them and they made hopeful noises about new API but I was on vacation for the last 3 weeks. I will follow up now. However, M6 is the API freeze. I'm actually pretty mad about this (madder than Tom Roche must be!).
Steve, aren't you Mr. SWT? So I guess you could carry the clout with the PMC to bend the API freeze rules a bit. Alternatively, those changes could be made in time to make it to 3.1 M7, but not made part of the API... Like that you respect the API freeze, and the deal could be that the new features/methods/visibility of methods -while public- would be unsupported in the API, with a common agreement that the best effort will be made that make them public & official API in a 3.1.1 or something like that. That would really make those ugly patches go away. As a last resort, what about aspect enabling SWT -or something similar- to allow for external hooks/mods without API changes? I was quite impressed with Martin Lippert AJEER at EclipseCon.
I'm not mad about the API freeze but rather that we have been waiting on Apple for so long that the API freeze happened, causing this feature to probably not happen for 3.1, after I promised to do something about it for 3.1. I'm still working on it. API's can change after M6 but it's way harder to make it happen ... and that's a good thing at this stage in the game.
Sounds like getBounds() for Menu and MenuItem are in the pipeline. I'd like to request public implementations for ScrollBar, TabItem and TableColumn as well. For completeness, perhaps DragSource, DropTarget, TrayItem, Tracker, Tray should probably be supported as well.
Comment #80 From Gary Johnston 2005-04-08 14:21 > Sounds like getBounds() for Menu and MenuItem are in the pipeline. > I'd like to request public implementations for ScrollBar, TabItem > and TableColumn as well. For completeness, perhaps DragSource, > DropTarget, TrayItem, Tracker, Tray should probably be supported as > well. "Probably"? For completeness they should definitely be supported. For functionality, i.e. enabling folks to write their tests, DragSource and DropTarget are higher priority. I know at least one person who is trying to test drag'n'drop onto R*D's Page Data View. We have too much functionality that is only provided by context menuing or DnD, so we really need to be able to test both of those.
All Widgets (i.e., including non-Control Widgets) should also implement toDisplay(Point) & toDisplay(int, int).
I have 3.1-M6 (Eclipse Platform Version: 3.1.0 Build id: I20050401-1645) and I'm seeing org.eclipse.swt.widgets.TableItem > /*public*/ Rectangle getBounds () { Can this be restored to public-ness? Alternatively, is there another way to get the bounds of a TableItem that one has found without knowing its row and column (e.g. by matching its getText() or some setData()'ed key/value)?
Is there some reason that TableItem.getBounds(int) won't work for you?
Tao Weng 04/25/2005 10:39:05 AM: >>>> I got my UML2 regression test script fully automated with >>>> Abbot.swt. I have to say that Abbot.swt is a great product. <more shameless plug snipped :-> >>>> By the way, I have changed a little bit of Abbot.swt in order to >>>> make my UML2 regression test script run. I do not know whether >>>> those changes are valid or not, so I don't want to do any check >>>> in. I would like to let you know. <big snip> >>>> 3) In abbot.tester.swt.WidgetLocator, I have to add the following >>>> piece of code in "getBounds" function. >>>> if(w instanceof TableItem){ >>>> TableItem item = (TableItem)w; >>>> Rectangle bounds = item.getBounds(); >>>> Point p = item.getParent().toDisplay(bounds.x,bounds.y); >>>> return new Rectangle(p.x,p.y,bounds.width,bounds.height); >>>> } Tom Roche 2005-05-09 21:58 >>> I have 3.1-M6 (Eclipse Platform Version: 3.1.0 Build id: >>> I20050401-1645) and I'm seeing >>> org.eclipse.swt.widgets.TableItem >>> > /*public*/ Rectangle getBounds () { >>> Can this be restored to public-ness? Alternatively, is there >>> another way to get the bounds of a TableItem that one has found >>> without knowing its row and column (e.g. by matching its getText() >>> or some setData()'ed key/value)? steve_northover@ca.ibm.com 2005-05-10 08:31 >> Is there some reason that TableItem.getBounds(int) won't work for >> you? As stated above, tests need to be able to get the bounds for a TableItem of which the column index is unknown. Is there API to get the column index for a TableItem? If not: org.eclipse.swt.widgets.TableItem.getBounds(int) > /** > * Returns a rectangle describing the receiver's size and location > * relative to its parent at a column in the table. > * > * @param index the index that specifies the column > * @return the receiver's bounding column rectangle seems to require the user to know the TableItem's column index. Am I missing something?
Use getBounds(0).
Steve Northover 2005-05-10 12:38 > Use getBounds(0). If TableItem.getBounds(0) == TableItem.getBounds(), why not instead public Rectangle getBounds () { return getBounds (0); } and refactor the current code /*public*/ Rectangle getBounds () { checkWidget(); if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED); int itemIndex = parent.indexOf (this); if (itemIndex == -1) return new Rectangle (0, 0, 0, 0); RECT rect = getBounds (itemIndex, 0, true, false); int width = rect.right - rect.left, height = rect.bottom - rect.top; return new Rectangle (rect.left, rect.top, width, height); } into some other private API? What purpose is served by not providing the same signature for TableItem?
TableItem.getBounds() was intended to return the same thing as Tree.getBounds () now that Tree's have columns. To be exact, the bounds of the text not including the item but the code didn't get implemented on all platforms. This would make Tree and Table API consistent (right now Table is missing the method). Would you like me to delete it? I can't make it public because we are API frozen.
steve_northover@ca.ibm.com 2005-05-10 13:55 ------- > TableItem.getBounds() was intended to return the same thing as > Tree.getBounds () now that Tree's have columns. To be exact, the > bounds of the text not including the item but the code didn't get > implemented on all platforms. This would make Tree and Table API > consistent (right now Table is missing the method). > Would you like me to delete it? I can't make it public because we > are API frozen. <sigh/> No, we'll just wait for a thaw. abbot.swt has plenty other SWT workarounds right now, what's one more ...
I meant to say "To be exact, the bounds of the text not including the image". I'm not sure exactly how not having this API is holding you back. I'm also really sorry for missing the 3.1 release for this bug report.
Steve Northover 2005-05-10 14:33 ------- > I'm not sure exactly how not having this API is holding you back. We continue to need Widget.getBounds(). Everything that holds that back requires workarounds. We have done workarounds for this issue (TableItem.getBounds()) and others on win32, but we don't have the resources to workaround for Carbon, GTK, etc. Lots of folks want programmatic automation, mostly for developer testing. (Some for other purposes--Larry Bergman is doing really cool extensions for demo/doc/pedagogy, maybe even TVT.) All we ask is for SWT to provide a firm foundation for programmatic automation (as Swing does). > I'm also really sorry for missing the 3.1 release for this bug > report. Me too--I would love for Abbot 1.0 to have multiplatform support. Todd Brackett: we're told that SWT's fix for this bug is just waiting for Apple to enable MenuItem.getBounds() for Carbon. If correct, can you give us an ETA?
You can get the information you need already for the TableItem on all platforms so I'm not sure what you are working around in this particular case.
Steve Northover 2005-05-10 14:33 ------- >>> I'm not sure exactly how not having this API is holding you back. Tom Roche 2005-05-10 15:55 ------- >> We continue to need Widget.getBounds(). I.e. getBounds() for each child of Widget. >> Everything that holds that back requires workarounds. Steve Northover 2005-05-10 16:11 ------- > You can get the information you need already for the TableItem on > all platforms so I'm not sure what you are working around in this > particular case. The non-public-ness of TableItem.getBounds(). As previously mentioned. I'm not sure what isn't clear here. We need getBounds() to find things. We have Component.getBounds(), we need Widget.getBounds(). Forgive the repetition, but "Everything that holds [Widget.getBounds()] back requires workarounds." (E.g. Abbot works around AWT MenuComponent's, but fortunately JMenuItem has mostly superceded that, and JMenuItem isa Component.) What we can find, we can automate--knock wood, but it's been true so far, threading be damned. Automation is good. Automation allows your users to create more/better tests--which means we develop better UIs faster--and automation allows your users to drive their code for demos, TVT, etc. Code-centric automation is better: it enhances developer-time testing and supports TDD. Multi-platform code-centric automation is better yet. Automation requires coordinate finding. Swing supports automation via a single API, Component.getBounds(), the sufficiency of which is evinced by the number of code-centric tools that build on that simple foundation, the functionality those tools provide, the number of their users, and the goodness of the UIs their users develop. That's good. That's important. If you can give SWT automation a similar foundation, Eclipse+JUnit+Abbot can deliver similar goodness a lot more/faster. Otherwise we hafta workaround you.
I do second Tom on that one. > "Everything that holds [Widget.getBounds()] back requires workarounds." I am faced with the exact same issues for the plug-in I am working on. Shall I continue to leave in the underworld of patched SWT? And I am dying to use abbot for my tests. Steve, in comment #79 you replied to me: > API's can change after M6 but it's way harder to make it > happen ... and that's a good thing at this stage in the game. I guess that this bugzilla has enough votes and followers to carry some weight and do some thing about it. You can make API change happen, you said it. I feel kind of let down here. Now, over 42 unique individuals, including 23 positives votes, the rest as CC are following this bug! I wish all bugs were so popular! Just some of the folks and companies which are represented in the CC on this bug, based on the voters and CCed emails: (excluding all the IBM folks in the US, Canada, and Switzerland ;-) ) *Eclipse board and strategic members: SAP Intel *Add-in provider members like: Agitar Instantiations *Companies like: Apple RIM (the blackberry guys) Orbeon Worldpac Trigeo *Open source projects: empproject, abbot, orbeon, oxf studio, vence, easyeclipse, eclipse-ccase, harbour-ide *Eclipse advocates and bloggers like Luis de la Rosa, and Gunnar Wagenknecht *Plus at least two academic institutions.... I think it is enough justification to give a push and make it so that it goes into 3.1 !
The original discussion was about TableItem.getBounds(), which you do not need today in order to make Abbot work. I agree that you need the general capability to get widget coordinates. You are free to contribute the code that does this at any time. In the case of MenuItem.getBounds() and Menu.getBounds(), we are stuck on Apple and have been for a while. There is nothing I can do about this. So, the right thing for you to do in the short term is to include platform specific code in Abbot and not to support Abbot on the Mac. This is sad, but it is the right software engineering thing to do. Please stop ranting at me. I am doing all I can and it doesn't help.
Philippe, the bug is important and we are doing all we can. The implications of adding an API like Widget.getBounds() (or solving this problem in another way) are big. We cannot propose API that is no-portable. We realize this bug is important and have been trying to get to it for a while.
Steve, First I would like you to kindly accept my public apologies if I came out hard and harsh. This may be my French way of loving heated arguments and debates resurfacing now and then ;-) I want you to be my best buddy, and I have serious respect for the work you guys are doing.Being the API guardians of the essential SWT must be a tough job, with trolls like me ruining your day! In all fairness, if some irresponsible person had given me your job, SWT would have been a half-baked, ugly, buggy, non-portable piece of crap, instead of the elegant work it is today and Eclipse would be dying from my incompetence :-) Be assured that if I need to vent my SWT frustration in the future, I will do it 1-on-1 first. Now, right after posting that unruly comment yesterday, I was hanging @ #eclipse and chatted with Billy B. who gave me some valuable insights. Also I did not really understand until now that the menu problem on Mac is real hard, and may not be solvable in a portable way because the way carbon handles menu bars. As far as I am concerned, I need the menu and menu items coordinates (MenuItem.getBounds() and Menu.getBounds() ), but I can live without portability, and Billy told me there could be a way to do it in my plug-in, probably without having to resort to SWT patching, or weird aspects, reflection or byte code hacks, as long as portability was not the major concern. And for me it is not. I care about making my own little plugin run nicely on top of a vanilla Eclipse build, with decent support for at least Windows, Mac and Linux/GTK. And if some features are NOT available on Mac, then so be it. I can live with that, and I can inform my users properly about the capabilities of that plugin on each platforms, both in the documentation and at run-time. I also care about SWT staying homogenous, elegant and portable on all Eclipse's platforms, and do not want to be an architect of its demise. If there is a way to get some code examples for Win and GTK posted somewhere to get me started, that would be great. And as far as I am concerned, that would close that bug! Cordially
Ok, thanks Philippe, I wouldn't go quite that far. If you are looking for the code that does Menu.getBounds() and MenuItem.getBounds(), it is also released as /*public*/ but doesn't work on the Mac. NOTE: Since many operating systems don't compute the menu bounds until the menu is about to be shown, the bounds are zero when the menu is not displayed. Also, this the coordinate systems are consistent but might not be the same when the code is finally released (sometime in the year 3000). It should be easy enough to do the same thing that Tom is doing (ie. copy the code to a platform specific utility class) and call it. Maybe Tom could provide his utility class as a patch in this bug report? Also, BB should be commenting in the bug report rather than chatting privately!
Steve, since Menu.getBounds() and MenuItem.getBounds() are /*public*/, I can work around that with reflection, as long I am not under the control of a restrictive security manager. A bit awkward, but the hack will do the trick for me, together with some platform specific conditions for macs or platforms where it returns odd or (0,0,0,0) values >NOTE: Since many operating systems don't compute the menu bounds >until the menu is about to be shown, the bounds are zero when the menu is not displayed. In my case that would not be a problem. I really only need to compute the menu bounds just right after they have been displayed, not before. >It should be easy enough to do the same thing that Tom is doing > (ie. copy the code to a platform specific utility class) and call it. Does not this require a patched SWT and therefore a modified core eclispe? I am trying to avoid that. Tom your patch would be welcomed or is it already in abbot? If so, I will do a diff again between SWT and your latest patched SWT, last I made is a few months old.
Just adding a quick note for everybody's understanding is that all Billy told me about this bug in our chat was it was down to the Mac menu issues. ;-)
Steve Northover 2005-05-11 08:03 [reply] ------- >>> Please stop ranting at me. I am doing all I can and it doesn't >>> help. Not ranting, just explaining, since the rationale for getBounds() (vs getBounds(...), yourAPIhere(...), etc) doesn't seem to take. Steve Northover 2005-05-11 16:15 [reply] ------- >> If you are looking for the code that does Menu.getBounds() and >> MenuItem.getBounds(), it is also released as /*public*/ but doesn't >> work on the Mac. The code in org.eclipse.swt.widgets.MenuItem.getBounds() in 3.1-M6 also works incorrectly on win32 when used to exercise a workbench: will post separately regarding that. >> NOTE: Since many operating systems don't compute the menu bounds >> until the menu is about to be shown, the bounds are zero when the >> menu is not displayed. Also, this the coordinate systems are >> consistent but might not be the same when the code is finally >> released (sometime in the year 3000). >> It should be easy enough to do the same thing that Tom is doing >> (ie. copy the code to a platform specific utility class) and call >> it. Maybe Tom could provide his utility class as a patch in this >> bug report? Philippe Ombredanne 2005-05-11 16:31 [reply] ------- > Steve, since Menu.getBounds() and MenuItem.getBounds() are > /*public*/, I can work around that with reflection, as long I am not > under the control of a restrictive security manager. A bit awkward, > but the hack will do the trick for me, together with some platform > specific conditions for macs or platforms where it returns odd or > (0,0,0,0) values >> NOTE: Since many operating systems don't compute the menu bounds >> until the menu is about to be shown, the bounds are zero when the >> menu is not displayed. > In my case that would not be a problem. I really only need to > compute the menu bounds just right after they have been displayed, > not before. >> It should be easy enough to do the same thing that Tom is doing >> (ie. copy the code to a platform specific utility class) and call >> it. > Does not this require a patched SWT and therefore a modified core > eclispe? No longer. > Tom your patch would be welcomed or is it already in abbot? It is: the patches are in abbot.swt.SWTWorkarounds http://cvs.sourceforge.net/viewcvs.py/*checkout*/abbot/abbot.swt/src/abbot/swt/SWTWorkarounds.java?rev=HEAD but they are transparent to the user: just use your Matcher's, Finder's, and Tester's and they will call the correct code for location. > If so, I will do a diff again between SWT and your latest patched > SWT, last I made is a few months old. Quit patching !-) See http://sourceforge.net/mailarchive/message.php?msg_id=11730297
Steve Northover 2005-05-11 16:15 >> If you are looking for the code that does Menu.getBounds() and >> MenuItem.getBounds(), it is also released as /*public*/ but doesn't >> work on the Mac. Tom Roche 2005-05-12 13:46 > The code in org.eclipse.swt.widgets.MenuItem.getBounds() in 3.1-M6 > also works incorrectly on win32 when used to exercise a workbench: > will post separately regarding that. When exercising a workbench, the code in 3.1-M6/ org.eclipse.swt.widgets.MenuItem.getBounds(), massaged slightly to run from our different package, clicks below the menubar, activating the toolbar button immediately below the targeted menu item. I suspect it returns a y value that is too large. This behavior was originally reported by other members of the abbot-users list. How to reproduce (in a 3.1-M6 workbench, untested with other versions, on win32, untested with other WSs): 0 Create a clean devspace folder, and start a workbench pointing to it. 1 Checkout/install/build the abbot, abbot.swt, and abbot.swt.eclipse modules from SourceForge CVS as described in http://cvs.sourceforge.net/viewcvs.py/*checkout*/abbot/abbot.swt/doc/swt/building.html#sourceAbbot Note that the abbot.swt.* modules are both eclipse plugins "out of the box," and so build "normally" in eclipse (e.g. with C-b), but that the abbot module is not--it's IDE-agnostic and requires an ant build (target=eclipse.setup) to attain plugin-hood in your workspace. (Hence turning off autobuild is advised before you start checkout.) 2 Create a JUnit Plugin Test with test class= abbot.swt.eclipse.tests.MenuItemGetBoundsTest running in a blank runspace (check Clear workspace data before launching) using the workbench's JRE (Runtime JRE=eclipse). Run it: A Java project will be created (headlessly), then 2 tests will run (it's {pretty fast, hard to see} but you can see the mouse move): the first clicks Run>ExternalTools>ExternalTools to launch that wizard, and the second clicks File>New>Other to launch the New wizard. (The JUnit view will green bar, but will report 4/4 due to inheritance.) Remove the terminated session in the Console view (call me anal, but pde.junit has some bugs/quirks that I try to accomodate ... or I may just be superstitious). 3 Open abbot.swt.SWTWorkarounds in an editor and browse to getBounds (MenuItem menuItem). Note that it currently contains + public static Rectangle getBounds (MenuItem menuItem) { + // start code from 3.1-M6 org.eclipse.swt.widgets.MenuItem.getBounds() + // checkWidget (); + // not visible, but menuItem.getParent() will call it + // Menu parent = menuItem.getParent(); + // if (OS.IsWinCE) return new Rectangle (0, 0, 0, 0); + // int index = parent.indexOf (menuItem); + // if (index == -1) return new Rectangle (0, 0, 0, 0); + // if ((parent.getStyle() & SWT.BAR) != 0) { + // Decorations shell = parent.getParent(); + // if (shell.getMenuBar() != parent) { + // return new Rectangle (0, 0, 0, 0); + // } + // int hwndShell = shell.handle; + // MENUBARINFO info1 = new MENUBARINFO (); + // info1.cbSize = MENUBARINFO.sizeof; + // if (!OS.GetMenuBarInfo (hwndShell, OS.OBJID_MENU, 1, info1)) { + // return new Rectangle (0, 0, 0, 0); + // } + // MENUBARINFO info2 = new MENUBARINFO (); + // info2.cbSize = MENUBARINFO.sizeof; + // if (!OS.GetMenuBarInfo (hwndShell, OS.OBJID_MENU, index + 1, info2)) { + // return new Rectangle (0, 0, 0, 0); + // } + // int x = info2.left - info1.left; + // int y = info2.top - info1.top; + // int width = info1.right - info1.left; + // int height = info1.bottom - info1.top; + // return new Rectangle (x, y, width, height); + // } else { + // int hMenu = parent.handle; + // RECT rect1 = new RECT (); + // if (!OS.GetMenuItemRect (0, hMenu, 0, rect1)) { + // return new Rectangle (0, 0, 0, 0); + // } + // RECT rect2 = new RECT (); + // if (!OS.GetMenuItemRect (0, hMenu, index, rect2)) { + // return new Rectangle (0, 0, 0, 0); + // } + // int x = rect2.left - rect1.left + 2; + // int y = rect2.top - rect1.top + 2; + // int width = rect2.right - rect2.left; + // int height = rect2.bottom - rect2.top; + // return new Rectangle (x, y, width, height); + // } + // end code from 3.1-M6 org.eclipse.swt.widgets.MenuItem.getBounds() + // start code adapted from o.e.swt.patched.MenuItem.getBounds() + Menu parent = menuItem.getParent(); + Decorations parentControl = parent.getParent(); + if (OS.IsWinCE) return new Rectangle (0, 0, 0, 0); + int index = parent.indexOf (menuItem); + if (index == -1) return new Rectangle (0, 0, 0, 0); + RECT rect = new RECT(); + boolean success = OS.GetMenuItemRect(((parent.getStyle()&SWT.BAR)==SWT.BAR)?parentControl.handle:0, + parent.handle, + index, + rect); + if (!success) { + /* the OS API call couldn't get the MenuItem bounds, so return an empty rectangle */ + return new Rectangle(0, 0, 0, 0); + } + if ((parentControl.getStyle() & SWT.MIRRORED) == 0) { + /* coordinates are not mirrored */ + Point p = parentControl.toControl(rect.left,rect.top); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + return new Rectangle(p.x,p.y,width,height); + } else { + /* coordinates are mirrored */ + /* TODO: this has not been tested */ + Point p = parentControl.toControl(rect.left,rect.top); + int width = rect.left - rect.right; + int height = rect.bottom - rect.top; + return new Rectangle(p.x,p.y,width,height); + } + // end code adapted from o.e.swt.patched.MenuItem.getBounds() + } The first section is minimally adapted from 3.1-M6/ org.eclipse.swt.widgets.MenuItem.getBounds(), the latter is from Abbot's patches. Note that the latter section is what you just ran successfully. Comment out that latter section, and uncomment the first section, to produce - public static Rectangle getBounds (MenuItem menuItem) { - // start code from 3.1-M6 org.eclipse.swt.widgets.MenuItem.getBounds() - // checkWidget (); - // not visible, but menuItem.getParent() will call it - Menu parent = menuItem.getParent(); - if (OS.IsWinCE) return new Rectangle (0, 0, 0, 0); - int index = parent.indexOf (menuItem); - if (index == -1) return new Rectangle (0, 0, 0, 0); - if ((parent.getStyle() & SWT.BAR) != 0) { - Decorations shell = parent.getParent(); - if (shell.getMenuBar() != parent) { - return new Rectangle (0, 0, 0, 0); - } - int hwndShell = shell.handle; - MENUBARINFO info1 = new MENUBARINFO (); - info1.cbSize = MENUBARINFO.sizeof; - if (!OS.GetMenuBarInfo (hwndShell, OS.OBJID_MENU, 1, info1)) { - return new Rectangle (0, 0, 0, 0); - } - MENUBARINFO info2 = new MENUBARINFO (); - info2.cbSize = MENUBARINFO.sizeof; - if (!OS.GetMenuBarInfo (hwndShell, OS.OBJID_MENU, index + 1, info2)) { - return new Rectangle (0, 0, 0, 0); - } - int x = info2.left - info1.left; - int y = info2.top - info1.top; - int width = info1.right - info1.left; - int height = info1.bottom - info1.top; - return new Rectangle (x, y, width, height); - } else { - int hMenu = parent.handle; - RECT rect1 = new RECT (); - if (!OS.GetMenuItemRect (0, hMenu, 0, rect1)) { - return new Rectangle (0, 0, 0, 0); - } - RECT rect2 = new RECT (); - if (!OS.GetMenuItemRect (0, hMenu, index, rect2)) { - return new Rectangle (0, 0, 0, 0); - } - int x = rect2.left - rect1.left + 2; - int y = rect2.top - rect1.top + 2; - int width = rect2.right - rect2.left; - int height = rect2.bottom - rect2.top; - return new Rectangle (x, y, width, height); - } - // end code from 3.1-M6 org.eclipse.swt.widgets.MenuItem.getBounds() - // start code adapted from o.e.swt.patched.MenuItem.getBounds() - // Menu parent = menuItem.getParent(); - // Decorations parentControl = parent.getParent(); - // if (OS.IsWinCE) return new Rectangle (0, 0, 0, 0); - // int index = parent.indexOf (menuItem); - // if (index == -1) return new Rectangle (0, 0, 0, 0); - // RECT rect = new RECT(); - // boolean success = OS.GetMenuItemRect(((parent.getStyle()&SWT.BAR)==SWT.BAR)?parentControl.handle:0, - // parent.handle, - // index, - // rect); - // if (!success) { - // /* the OS API call couldn't get the MenuItem bounds, so return an empty rectangle */ - // return new Rectangle(0, 0, 0, 0); - // } - // if ((parentControl.getStyle() & SWT.MIRRORED) == 0) { - // /* coordinates are not mirrored */ - // Point p = parentControl.toControl(rect.left,rect.top); - // int width = rect.right - rect.left; - // int height = rect.bottom - rect.top; - // return new Rectangle(p.x,p.y,width,height); - // } else { - // /* coordinates are mirrored */ - // /* TODO: this has not been tested */ - // Point p = parentControl.toControl(rect.left,rect.top); - // int width = rect.left - rect.right; - // int height = rect.bottom - rect.top; - // return new Rectangle(p.x,p.y,width,height); - // } - // end code adapted from o.e.swt.patched.MenuItem.getBounds() - } Save and build. 4 Rerun abbot.swt.eclipse.tests.MenuItemGetBoundsTest (e.g. with C-F11). Note that, instead of clicking the menu, the mouse clicks the Search button on the toolbar, and the Search wizard launches instead of External Tools. (Note that the button and mouse are positioned just below the Run item in the menu bar, hence my hypothesis.) This hoses that and subsequent tests with abbot.WaitTimedOutError: Timed out waiting for External Tools to show at abbot.tester.swt.Robot.wait(Robot.java:1454) at abbot.tester.swt.Robot.wait(Robot.java:1442) at abbot.tester.swt.WidgetTester.waitForShellShowing(WidgetTester.java:897) at abbot.swt.eclipse.tests.MenuItemGetBoundsTest$1.run(MenuItemGetBoundsTest.java:82) in the Console. 5 If desired, whack the session, undo the changes to SWTWorkarounds, save, C-b, C-F11: the tests again run successfully to completion by correctly clicking the menu items. All: please let me know if you are able to reproduce or not, especially if the directions are unclear.
The part that is unclear is whether you know what the bug is already and have a fix. If this is the case, can you please post the patch? Thanks.
Created attachment 21077 [details] adaption of code that fixes bad menu-picking as demonstrated in https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c102 See https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c102 https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c104
Steve Northover 2005-05-12 18:34 > The part that is unclear is whether you know what the bug is already Umm ... it seems pretty clear that the bug is in the code adapted from 3.1-M6 org.eclipse.swt.widgets.MenuItem.getBounds(), since the test fails when using that code, no? > and have a fix. If this is the case, can you please post the patch? https://bugs.eclipse.org/bugs/attachment.cgi?id=21077 but note that I can't verify the patched code directly ... because I hafta workaround the non-public-ness of MenuItem.getBounds().
Tom, the more you help me, the more I can help you. A single sentence like "The problem is that the coordinates are wrong because ... or mirroring is not taken into account ..." would be most appreciated (unless you really have no idea what is wrong, in which case saying so helps too, but you have a patch so that implies you do know what's going on). It's just easier not to have to guess from the code but I can do that if you want. It'll just take longer. Also, a small stand alone test case that uses the API is really helpful rather than downloading and installing Abbot. If you don't have the code, then that's fine too. Billy, can you verify that the patch doesn't compile?
Tom Roche 2005-05-12 18:07 >>> When exercising a workbench, the code in 3.1-M6/ >>> org.eclipse.swt.widgets.MenuItem.getBounds(), massaged slightly to >>> run from our different package, clicks below the menubar, >>> activating the toolbar button immediately below the targeted menu >>> item. I suspect it returns a y value that is too large. steve_northover@ca.ibm.com 2005-05-13 08:50 >> A single sentence like "The problem is that the coordinates are >> wrong because ... or mirroring is not taken into account ..." would >> be most appreciated Steve: what part of "returns a y value that is too large" is unclear? >> (unless you really have no idea what is wrong, in which case saying >> so helps too, but you have a patch so that implies you do know >> what's going on). (The more helpful you claim to be, the more your language betrays you.) Not only have I an "idea what is wrong," I have given you a test case that clearly displays it! I even walk you through reproduction of the test case's behavior: >>> 2 Create a JUnit Plugin Test with test class= >>> abbot.swt.eclipse.tests.MenuItemGetBoundsTest[....] 2 tests will >>> run (it's {pretty fast, hard to see} but you can see the mouse >>> move): the first clicks Run>ExternalTools>ExternalTools to >>> launch that wizard, and the second clicks File>New>Other to >>> launch the New wizard. <snip> >>> 3 Open abbot.swt.SWTWorkarounds in an editor and browse to >>> getBounds (MenuItem menuItem)[....] Comment out that latter >>> section, and uncomment the first section <snip> >>> 4 Rerun abbot.swt.eclipse.tests.MenuItemGetBoundsTest (e.g. with >>> C-F11). Note that, instead of clicking the menu, the mouse clicks >>> the Search button on the toolbar, and the Search wizard launches >>> instead of External Tools. >> It's just easier not to have to guess from the code but I can do >> that if you want. It'll just take longer. You know I don't want that, Steve: that's why I show you how to actually reproduce the problem. Why "guess from the code" when you can *observe* the behavior? >> Also, a small stand alone test case that uses the API is really >> helpful rather than downloading and installing Abbot. Keep in mind here that the code in question (MenuItem.getBounds()) is required for automation. In order to empirically assess the correctness of the code, you're gonna hafta have some automation framework. I note http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/test_plan.html > 1. Ensure all public API is exercised through a JUnit test > - we have an automated tool to do this but we have not made it > publicly accessible yet but it seems to have been that way for a while :-) Unfortunately automation seems to require a fair amount of infrastructure. Fortunately, in this case the infrastructure amounts to all of 3 plugins. Is that so onerous? (Perhaps your non-public automation tool is more svelte? We'd love to see it !-) You can get/install it, and reproduce the problem, in all of 15 minutes (on LAN). If you'd like, I can build binary plugin zips for abbot and abbot.swt for you: unfortunately pde.junit currently can't run tests outside the workbench, so you'd still hafta get that as source. Note that I'm putting my automation framework out there for you and everyone to use, and to reproduce this problem, because ya gotta test, Steve, not just eyeball the code. We even expose our tests as JUnit testcases that are easily run via Eclipse's builtin tooling! (Never let it be said that I don't try to help you help me :-) So until you put *your* automation tool out there for folks to use, I don't see a feasible alternative to the following for testing this bug: 0 Reproduce the problem as detailed in https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c102 1 Twiddle the code in abbot.swt.SWTWorkarounds.getBounds(MenuItem) as desired, then test using abbot.swt.eclipse.tests.MenuItemGetBoundsTest 2 Repeat step 1 until you get the code the way you want it, and it passes the test. For extra credit, run abbot.swt.examples.CelsiusConverterFindingTest and abbot.swt.examples.CelsiusConverterTest as JUnit tests (i.e. Run>Run>JUnit, not Run>Run>JUnit Plugin Test)--they also pass with the HEAD of abbot.swt.SWTWorkarounds.getBounds(MenuItem). 3 Copy/mod your code from abbot.swt.SWTWorkarounds.getBounds(MenuItem) back into org.eclipse.swt.widgets.MenuItem.getBounds(). (Then, make it public !-)
> Keep in mind here that the code in question (MenuItem.getBounds()) is > required for automation. In order to empirically assess the > correctness of the code, you're gonna hafta have some automation > framework. I note > http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt- home/test_plan.html > > 1. Ensure all public API is exercised through a JUnit test > > - we have an automated tool to do this but we have not made it > > publicly accessible yet > but it seems to have been that way for a while :-) Unfortunately > automation seems to require a fair amount of infrastructure. > Fortunately, in this case the infrastructure amounts to all of 3 > plugins. You won't know if a snippet will reproduce the problem until you've actually tried it. I don't see why querying menu location would require some sort of complex setup or series of events to reproduce the problem. Just create a Shell, slap a menubar on it, call the package protected API, and place a tracker over that rectangle highlighting the bogus bounds. Not only is this easier for Steve, but it removes the however small chance that Abbot is doing something wrong.
Please Tom, just stop. I'm not trying to imply anything or do anything other that find out what is wrong and fix it.
Randy: if you can, please contribute a snippet that launches a workbench and tests MenuItem.getBounds() against it. If you can't, please *try* to reproduce the bug as described, and ask where the descriptions are unclear. I suspect you'll find that installing the code and running the tests is not so nearly so onerous as you suspect (and probably a helluva lot less onerous than writing the snippet :-) Randy Hudson 2005-05-13 11:34 > You won't know if a snippet will reproduce the problem until you've > actually tried it. True, but I suspect you're overlooking 2 problems: 0 Testcases show the problem occurring with SUT=workbench, not SUT=a standalone app (more below) 1 I don't know how to do a snippet that would (adapted for what actually needs done) > Just [launch a workbench, find one of its MenuItem's], and place a > tracker over that rectangle highlighting the bogus bounds. First, please note: Tom Roche 2005-05-12 18:07 >>> When exercising a workbench, That's the important part: exercising a workbench. >>> the code in 3.1-M6/ org.eclipse.swt.widgets.MenuItem.getBounds(), >>> massaged slightly to run from our different package, clicks below >>> the menubar, activating the toolbar button immediately below the >>> targeted menu item. I suspect it returns a y value that is too >>> large. Second, note that Abbot also works against standalone SWT: in fact we have an example standalone SWT app and publically-available tests that run against it: >> For extra credit, run >> abbot.swt.examples.CelsiusConverterFindingTest and >> abbot.swt.examples.CelsiusConverterTest as JUnit tests (i.e. >> Run>Run>JUnit, not Run>Run>JUnit Plugin Test)--they also pass >> with the HEAD of abbot.swt.SWTWorkarounds.getBounds(MenuItem). Third, I know, from running those Celsius*Test's, that both code sections in abbot.swt.SWTWorkarounds.getBounds(MenuItem) >>> The first section is minimally adapted from 3.1-M6/ >>> org.eclipse.swt.widgets.MenuItem.getBounds(), the latter is from >>> Abbot's patches. Note that the latter section is what you just >>> ran successfully. Comment out that latter section, and uncomment >>> the first section work in the standalone case. The difference is the workbench case as described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c102 In that case, our code STILL works, but the code derived from org.eclipse.swt.widgets.MenuItem.getBounds() fails. Finally, please note that the *only* reason why abbot.swt resorts to adapting org.eclipse.swt.widgets.MenuItem.getBounds() is because Steve has made it non-public. Were it public, we could call it directly, without resorting to abbot.swt.SWTWorkarounds. So if you can do a snippet that launches a workbench, finds one of its mainmenu items and highlights the bounds, please do, because you are certainly correct that > it [would remove] the however small chance that Abbot is doing > something wrong. I am certainly not claiming that Abbot or abbot.swt is without fault: we're trying to get an RC1 out and our users are making very clear where our faults and function gaps are :-) What I am doing is making an SWT automation framework publically available (IIRC the *only* publically available SWT automation framework, which is why so many folks want this fixed), making testcases publically available, publically demonstrating how to reproduce a problem--and even publically demonstrating code that FIXES the problem! (Feel free to demonstrate where *that* is at fault. Til then, honi soit qui mal y pense.)
SN, here's the snippet: public static void main(String[] args) { Display display = new Display (); Shell shell = new Shell (display); Menu bar = new Menu (shell, SWT.BAR); shell.setMenuBar (bar); MenuItem fileItem = new MenuItem (bar, SWT.CASCADE); fileItem.setText ("File"); Menu submenu = new Menu (shell, SWT.DROP_DOWN); fileItem.setMenu (submenu); MenuItem item = new MenuItem (submenu, SWT.PUSH); item.setText ("Select &All\tCtrl+A"); item.setAccelerator (SWT.CTRL + 'A'); shell.setSize (200, 200); shell.open (); try { Method m = fileItem.getClass().getDeclaredMethods()[8]; System.out.println(m.toString()); m.setAccessible(true); Rectangle rect = (Rectangle)m.invoke(fileItem, null); Point where = new Point(rect.x, rect.y); where = shell.toDisplay(where); Shell highlight = new Shell(display, SWT.NO_TRIM | SWT.PRIMARY_MODAL); highlight.setBounds(where.x, where.y, rect.width, rect.height); highlight.setBackground(display.getSystemColor (SWT.COLOR_INFO_BACKGROUND)); highlight.open(); } catch (Exception e) { e.printStackTrace(); } while (!shell.isDisposed()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } BTW, if setAccelerator is not called, an exception gets thrown.
The problem is that MenuItem.getBounds() returns the coordinates in terms of the parent, which is a Menu. Menus are like Shells and use the coordinate system of the display, rather than their parent. So some coordinate math is necessary which is a bit bad but the best I can do right now. There was also a bug in MenuItem.getBounds() where the wrong width was returned on Windows. That bug has been fixed and released. Here is a better snippet: import java.lang.reflect.*; import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; public class PR_38436 { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); Menu bar = new Menu(shell, SWT.BAR); shell.setMenuBar(bar); MenuItem fileItem = new MenuItem(bar, SWT.CASCADE); fileItem.setText("File"); Menu submenu = new Menu(shell, SWT.DROP_DOWN); fileItem.setMenu(submenu); MenuItem item = new MenuItem(submenu, SWT.PUSH); item.setText("Select &All\tCtrl+A"); item.setAccelerator(SWT.CTRL + 'A'); shell.setSize(200, 200); shell.open(); try { Method m1 = bar.getClass().getDeclaredMethod("getBounds", null); m1.setAccessible(true); Rectangle menuRect = (Rectangle) m1.invoke(bar, null); Method m2 = fileItem.getClass().getDeclaredMethod("getBounds", null); m2.setAccessible(true); Rectangle itemRect = (Rectangle) m2.invoke(fileItem, null); if ((bar.getStyle() & SWT.RIGHT_TO_LEFT) != 0) { itemRect.x = menuRect.x + menuRect.width - itemRect.width - itemRect.x; } else { itemRect.x += menuRect.x; } itemRect.y += menuRect.y; Shell highlight = new Shell(display, SWT.NO_TRIM | SWT.PRIMARY_MODAL); highlight.setBounds(itemRect.x, itemRect.y, itemRect.width, itemRect.height); highlight.setBackground(display.getSystemColor (SWT.COLOR_INFO_BACKGROUND)); highlight.open(); } catch (Exception e) { e.printStackTrace(); } while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
I have run MenuItemGetBoundsTest. As SN described, the problem seems to be that Menu.getBounds() is returning its result in display coordinates and the code in WidgetLocator is translating these display relative coordinates using item.getParent().getParent().toDisplay(bounds.x,bounds.y); and this is not neccessary. The following works for me on Windows: In SWTWorkaround: public static Rectangle getBounds(MenuItem menuItem) { // start code adapted from <url>https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c112</url> Menu parent = menuItem.getParent(); Method m1 = null; try { m1 = parent.getClass().getDeclaredMethod("getBounds", null); } catch (SecurityException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } m1.setAccessible(true); Rectangle menuRect = null; try { menuRect = (Rectangle) m1.invoke(parent, null); } catch (IllegalArgumentException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } Method m2 = null; try { m2 = menuItem.getClass().getDeclaredMethod ("getBounds", null); } catch (SecurityException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } m2.setAccessible(true); Rectangle itemRect = null; try { itemRect = (Rectangle) m2.invoke(menuItem, null); } catch (IllegalArgumentException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO_Tom Auto-generated catch block e.printStackTrace(); } if ((parent.getStyle() & SWT.RIGHT_TO_LEFT) != 0) { itemRect.x = menuRect.x + menuRect.width - itemRect.width - itemRect.x; } else { itemRect.x += menuRect.x; } itemRect.y += menuRect.y; return itemRect; // end code adapted from <url>https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c112</url> } In WidgetLocator.getBounds(Widget, boolean): if(w instanceof MenuItem){ MenuItem item = (MenuItem)w; return SWTWorkarounds.getBounds(item); }
Veronika Irvine 05/16/2005 04:58:02 PM: >> I have reproduced the problem and seen that the code from M6 and >> from 38436#c112 both fail whereas "code adapted from o.e.swt. >> patched.MenuItem.getBounds()" works. Will investigate with Steve. Veronika Irvine 2005-05-16 17:55 > I have run MenuItemGetBoundsTest. As SN described, the problem seems > to be that Menu.getBounds() is returning its result in display > coordinates and the code in WidgetLocator is translating these > display relative coordinates using > item.getParent().getParent().toDisplay(bounds.x,bounds.y); and this > is not neccessary. Doh! I still don't understand why the translation only failed in- workbench and not standalone, but the tests now pass, which is what counts. Thanks so much!
For future consideration, I think the problem would be simplified if Menu supported toControl() and toDisplay(). That way you would not have to do the following math: if ((parent.getStyle() & SWT.RIGHT_TO_LEFT) != 0) { itemRect.x = menuRect.x + menuRect.width - itemRect.width - itemRect.x; } else { itemRect.x += menuRect.x; } itemRect.y += menuRect.y; Instead, you would just get the bounds of the MenuItem (itemRect in the code above) and call menuItem.getParent().toDisplay(itemRect.x, itemRect.y).
Yes, but more importantly, Display.map() needs to take more than just controls. Display.map() is the API that maps whole rectangles from RTL and LTR coordinate systems which is the right way to do coordinate transformations in a mirrored world.
org.eclipse.swt.custom.CTabFolder class do not expose any methods to get the Rectangle bounds of : 1) Chevron >>> button 2) Minimize/Maximize button 3) Close button In Eclipse 3.0 milestones releases, methods exists to get those bounds but they were removed. The implications for GUI Test Automation tool(IBM Rational Functional Tester) is that they CANNOT click on the chevron, min/max or close buttons and so cannot test complex cases where more views are stacked at a CTabFolder.
Created attachment 23906 [details] abbot.swt.SWTWorkarounds shelters users from Widget.getBounds()-related problems: cases where either Whatever.getBounds() is unavailable, not public, or has unwelcome behavior. Most up-to-date code, as well as code for users of abbot.swt.SWTWorkarounds (currently abbot.tester.swt.WidgetLocator abbot.tester.swt.MenuItemTester abbot.tester.swt.ScrollBarTester abbot.tester.swt.TableTester abbot.tester.swt.TreeItemTester ) is available (with null password) from cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/abbot co abbot.swt
Tao Weng 05/26/2005 11:43 AM >>> Currently, Abbot.swt solution is not platform independent due to >>> bugzilla defect number 38436. <snip> >>> 1) Is the defect going to be fixed within the next 6 months or so? >>> If not, when is it going to be available. Just roughly.... >>> 2) Is it possible to release a patched version of swt for linux >>> environment in the next 6 months. Just like what we did for windows? Steve Northover 05/26/2005 12:19:43 PM: >> Yes. Either the bug will be fixed or I will work with Tom to ensure >> that Abbot is patched to support Linux. Tom Roche 05/26/2005 10:15 PM > Thanks! >> Tom, if you contribute the [SWTWorkarounds] class from Abbot to >> the bug report, we will look at providing implementations for the >> other plaforms. > Will do soonest, just verifying a (candidate) fix for 3.0 first. Unfortunately soonest was much less soon than I had hoped :-( but I have refactored such that (IIUC) all abbot.swt's SWT workarounds are in abbot.swt.SWTWorkarounds, which is now attached. Apologies for the delay, your assistance is appreciated.
I am working on a version of SWTWorkarounds that can be used for 3.1. Hold the phone. Thomas, the implementation of swt2Awt() can't work anywhere else but Windows. The format of the KeyTable is platforms specific. Is this method critical to Abbot? (seems like it might be). Can you please recode this method either as a horrible huge case statement or a hash table and post the code here? Thanks!
We have the code ready but need an implementation of swt2Awt() before we can proceed.
Comment #120 From Steve Northover 2005-07-11 11:53 > I am working on a version of SWTWorkarounds that can be used for > 3.1. Great! Thanks for your cooperation! > Thomas, the implementation of swt2Awt() can't work anywhere else > but Windows. The format of the KeyTable is platforms specific. Steve, SWTWorkarounds.keyTable exists to enable SWTWorkarounds.swt2Awt(int swtKeyValue), and both are in SWTWorkarounds because ... they're more <bleep>ing workarounds for SWT. As the latter's javadoc states: /** * Translates from SWT keys values to AWT ones, e.g. * from <code>SWT.ESC</code> to <code>VK_ESCAPE</code>. * For details see * {@link org.eclipse.swt.widgets.Display#KeyTable} * Workaround for package scope of * {@link org.eclipse.swt.widgets.Display#untranslateKey(int)} */ So ... could you please just make Display.untranslateKey(int) public? instead of requiring Yet Another Workaround > Can you please recode this method either as a horrible huge case > statement or a hash table from your users?
Tom, I'm going to appeal one last time to please skip the editorial comments like "bleep" or "Yet Another WorkAround". They are offsensive, cloud the issue, waste time and make me wonder why on earth I would want to help someone who continually insults me and the work I do. Please read the rest of this comment and respond only to the technical issues. >Thomas, the implementation of swt2Awt() can't work anywhere else but >Windows. The format of the KeyTable is platforms specific. The package variable KeyTable maps SWT key constants to platform specific key constants. On Windows, keys like SWT.HOME are mapped to the Windows constant VK_HOME. On GTK, SWT.HOME is mapped to GDK_HOME. It does not map SWT key constants to AWT key constants and therefore cannot be made to do this. In addition, it does not make sense for SWT to provide a mechanism to map SWT constants to AWT constants. For one, AWT doesn't exist on all the platforms where SWT runs. So, if Abbot needs to make AWT constants to SWT constants for some reason, Abbot will need code to do this. Since I have no idea what this mapping is used for and cannot know from the source code in SWTWorkarounds, you are the most logical person to write the code and contribute it. Other than the mapping table, we are ready to go.
Comment #123 From Steve Northover 2005-07-12 13:20 > Tom, I'm going to appeal one last time to please skip the editorial > comments like "bleep" or "Yet Another WorkAround". Steve, lighten up, then > respond only to the technical issues. e.g. Comment #122 From Tom Roche 2005-07-12 12:06 >> could you please just make Display.untranslateKey(int) public? If not I'll try reflecting on it, which would presumably obviate the need for the local copy of org.eclipse.swt.widgets.Display.KeyTable (or am I missing something?)
The mapping table in Display is different on every platform. It maps SWT keys to platform specific keys, not AWT keys. Therefore it cannot be used. You will need to provide an implementation that maps SWT keys to AWT keys. Once we have that code, the 3.1 SWTWorkarounds patch will be complete.
To be even more precise, the mapping table will be portable and will live inside SWTWorkarounds.
Comment #125 From Steve Northover 2005-07-12 17:54 > The mapping table in Display is different on every platform. It maps > SWT keys to platform specific keys, not AWT keys. Therefore it > cannot be used. You will need to provide an implementation that maps > SWT keys to AWT keys. OK, will do. If you know of any tables with this information, please point.
I know of none.
Created attachment 25375 [details] org.eclipse.swt.widgets.SWTWorkarounds lives in Abbot, exposing needed package-privates to users
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c122 From Tom Roche 2005-07-12 12:06 >> could you please just make Display.untranslateKey(int) public? https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c125 From Steve Northover 2005-07-12 17:54 > The mapping table in Display is different on every platform. It > maps SWT keys to platform specific keys, not AWT keys. Therefore it > cannot be used. Apologies for the delay. Turns out that SWTWorkarounds.swt2Awt was a red herring: * it did _not_ translate from SWT to AWT key values * its caller needed translation from SWT to native, hence the local copy of Display.KeyTable. Please find https://bugs.eclipse.org/bugs/attachment.cgi?id=25375 attached. In addition to renaming the method, I also changed SWTWorkarounds' package to workaround the package-visibility issues: this allows SWTWorkarounds.swt2OS to call Display.untranslateKey(int) directly. I'll also try eliminate the reflection in getBounds(MenuItem) after we branch for 3.1. Meanwhile, https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c120 From Steve Northover 2005-07-11 11:53 >>> I am working on a version of SWTWorkarounds that can be used for >>> 3.1. Please lemme know if you find any other obstacles.
>Other than the mapping table, we are ready to go. 1) Please don't write any code or change anything in the SWTWorkarounds class (other than the mapping table). We are have been ready to go with the code for a while. No other work is necessary and changing anything else in the file may actually cause work. 2) Are you telling me that Abbot really needs to translate SWT keys to operating system keys in order to work? There is no API in SWT that will accept operating system key values and do anything sensible with them. Is there an API in AWT or Abbot that takes operating system key values? If so, how is Abbot for AWT getting these values? Is there AWT API that translates AWT key values to operating system key values?
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c131 From Steve Northover 2005-07-27 18:57 (rearranged) > 2) Are you telling me that Abbot really needs to translate SWT keys > to operating system keys in order to work? If you define "really" as in "SWT really needs to have a package- private Display.untranslateKey(int)," then yes: at the moment, in one place, it does. > 1) Please don't write any code or change anything in the > SWTWorkarounds class (other than the mapping table). We are have > been ready to go with the code for a while. No other work is > necessary and changing anything else in the file may actually cause > work. What has changed: * the package, allowing ... * ... keyTable (and initKeyTable(...)) to disappear, per your request * swt2Awt(...) -> swt2OS(...) * swt2OS(...) calls Display.untranslateKey(int) directly Since presumably none of your code used the local keyTable or called initKeyTable(...) or swt2Awt(...), you should have no problems.
Billy to go and get the Abbot source and find out what Abbot is doing with operating system key values to determine whether the API is needed or not and post the results in this bug report.
The only code I found that used swt2OS() was in TreeItemTester: new Robot().keyPress(SWTWorkarounds.swt2OS(SWT.ESC)); The method swt2OS(SWT.ESC) returns GDK_Escape (0xff1b) under GTK+. I cannot find any code path in Robot().keyPress() which expects a GDK key value, and sending 0xff1b to an AWT robot under GTK+ results in an invalid key code exception. I assume this works on Windows because SWT.ESC maps to Windows' VK_ESCAPE (0x1b) which I guess happens to have the same value as the AWT VK_ESCAPE. I don't think this function is actually useful to you. Is there somewhere else you intended to use this?
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c131 From Steve Northover 2005-07-27 18:57 >>> 2) Are you telling me that Abbot really needs to translate SWT >>> keys to operating system keys in order to work? https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c132 From Tom Roche 2005-07-27 19:27 >> If you define "really" as in "SWT really needs to have a package- >> private Display.untranslateKey(int)," then yes: at the moment, in >> one place, it does. https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c134 From Billy Biggs 2005-07-28 10:59 > The only code I found that used swt2OS() was in TreeItemTester: > new Robot().keyPress(SWTWorkarounds.swt2OS(SWT.ESC)); Correct. > The method swt2OS(SWT.ESC) returns GDK_Escape (0xff1b) under GTK+. I > cannot find any code path in Robot().keyPress() which expects a GDK > key value, and sending 0xff1b to an AWT robot under GTK+ results in > an invalid key code exception. I assume this works on Windows > because SWT.ESC maps to Windows' VK_ESCAPE (0x1b) which I guess > happens to have the same value as the AWT VK_ESCAPE. Doh! hafta do an swt2Awt after all ... > I don't think this function is actually useful to you. Is there > somewhere else you intended to use this? As stated above, just this one place. Doesn't mean it won't be useful in the future, but if you really can't tolerate its existence, feel free to remove: we can always add it back if needed.
> > As stated above, just this one place. Doesn't mean it won't be useful > in the future, but if you really can't tolerate its existence, feel > free to remove: we can always add it back if needed. > YAGNI
What Billy is trying to tell you is that this method is not only useless, it is also broken. It does not work on GTK. After examining the Abbot source code, we have determined that the intent of the method is to map SWT key values to AWT key values (not operating system key values as was previously claimed). Since Abbot calls swt2OS() in exactly one place, always with SWT.ESC and SWT.ESC maps to AWT's VK_ESCAPE, I suggest you change Abbot to simply inline AWT's VK_ESCAPE. To be more precise, change the line to TreeItemTester to be: new Robot().keyPress(KeyEvent.VK_ESCAPE)); Once this is done, we can release the patch.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c137 From Steve Northover 2005-07-28 13:39 > new Robot().keyPress(KeyEvent.VK_ESCAPE)); Done!
Created attachment 25431 [details] SWTWorkarounds for Abbot (SWT 3.1, Windows, GTK and Motif) Here is the SWTWorkarounds class for Abbot (SWT 3.1, Windows, GTK and Motif). NOTE: There is no work around code for the Mac due to missing operating system features for that platform and lack of support from Apple. Too bad!
should getBounds(Menu) call itself or getBounds((Object)menu);?
> should getBounds(Menu) call itself or getBounds((Object)menu);? ditto getBounds(MenuItem) ... that first stack overflow was attention-grabbing :-)
Oops, we didn't do a final test pass on everything (but the code should be close). Please attach a new class with your fixes when you have finished testing it. If you have any problems, let us know.
> Created an attachment (id=25431) [edit] > SWTWorkarounds for Abbot (SWT 3.1, Windows, GTK and Motif) > > Here is the SWTWorkarounds class for Abbot (SWT 3.1, Windows, GTK and Motif). This does not work properly for menu(item)s (I already added the cast to Object). The coordinates do not get mapped to display space coords. As I am not involved into abbot at all, I don't know whether this should happen in SWTWorkarounds or in WidgetLocator.getBounds(). However, SWTWorkarounds.getBounds(Menu menu) already answers display space coords for me (Linux/GTK). So, I added a itemRect.y += menuRect.y; in getBounds(MenuItem menuItem) and it seems to work fine for me. Here is the whole method: public static Rectangle getBounds(MenuItem menuItem) { Rectangle itemRect = getBounds ((Object)menuItem); Rectangle menuRect = getBounds (menuItem.getParent ()); if ((menuItem.getParent ().getStyle() & SWT.RIGHT_TO_LEFT) != 0) { itemRect.x = menuRect.x + menuRect.width - itemRect.width - itemRect.x; } else { itemRect.x += menuRect.x; } itemRect.y += menuRect.y; return itemRect; }
Created attachment 25499 [details] SWTWorkarounds for Abbot (SWT 3.1: Windows, GTK, Motif) https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c143 From i.maier@tu-bs.de 2005-08-01 06:08 > I added a > itemRect.y += menuRect.y; > in getBounds(MenuItem menuItem) and it seems to work fine for me. Thanks, Ingo Maier! Attachment also fixes the stack overflows. Remaining known issues: * tree item finding (e.g. in New Wizard dialog) requires "training": a test will fail the first time, but succeeds after first manual iteration. E.g. I observe the sequence [Run>Run><test>: fails, run the same scenario manually, Run>Run><test>: succeeds] with several tests (JavaProjectTester, WTPSimpleWebProjectTest, WTPWizardTest). * need to handle cases when method is unavailable * incomplete Carbon support
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38436#c144 > Remaining known issues: on win32: need reports from other platforms
Created attachment 25568 [details] SWTWorkarounds for Abbot (SWT 3.1: Windows, GTK, Motif) OK, here is the latest class. I tested the code on Windows, GTK and Motif. TOM: Do not put this class in org.eclipse.swt.widgets. It is temporary work around code specifically for Abbot. I put it in the package abbot.swt which was the original place you had the workaround.
>* tree item finding (e.g. in New Wizard dialog) requires "training": a > test will fail the first time, but succeeds after first manual Enter a new bug report for this. It has nothing to do with this bug report.
As I see, this topic is dead for a half year, and still not solved. From what I understood here, MenuItem on MacOS is stuck, but other widgets, which have fixed place (like TabItem) didn't run into this problem and could be implemented on all platforms. Couldn't this be done at least for widgets for which it is possible? Cause I see the need not only for automatic testing, but for general use (such as creating context menus for TabItem's).
I agree with you, however, we cannot offer API on one platform that cannot be implemented on another or SWT will cease to be portable.
That's really true, but I'm talking only about widgets, for which such functionality can be implemented on all platforms. This wouldn't break portability.
Steve, per our recent email exchange, would you please provide a workaround/patch implementation of getBounds() for TreeColumn (analogous to what we're using for some of the other non-Control Widgets in our SWTWorkarounds class in abbot.swt (on SourceForge)? Thanks.
NOTE: Our email exchange consisted of me asking Gary to ask for this new feature in the bug report.
Created attachment 56919 [details] SWTWorkarounds for Abbot (SWT 3.2: Windows, GTK, Motif) New versions of the code for 3.2.
Created attachment 74636 [details] extends SWT to add a getBounds method for MenuItem, and for TabItem, on OSX The enclosed code extends SWT to add a getBounds method for MenuItem, and for TabItem, on OSX. The way it does this is to use the Accessibility API. You must first have checked the item 'System Preferences/Universal Access/Enable access for assistive devices' This is unfortunate, but this seems like an acceptable cost for a test framework.
Comment on attachment 74636 [details] extends SWT to add a getBounds method for MenuItem, and for TabItem, on OSX
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.