Community
Participate
Working Groups
Created attachment 213531 [details] CTabFolderTraversalTest.java Eclipse 4.2 M6 Traverse around the Java perspective using the tab key on the keyboard. As always, you need to use Ctrl+Tab to traverse out of a multi-line text in the forward direction, and Ctrl+Shift+Tab to traverse out of a multi-line text in the reverse direction. For other controls, it is sufficient to use Tab and Shift+Tab for forward/reverse traversal. Notice that the traversal behavior is "different" from Eclipse 3.8, in that you do not get "stuck" in a View or Editor stack - you can, in fact, traverse everywhere in the perspective simply by using combinations of the Tab key, which is good. However, notice also that the behavior seems difficult to predict, because sometimes when you traverse to a CTabItem, focus is forced into the CTabItem's content, and sometimes it isn't. Reverse traversal usually follows a different path than forward traversal. What is actually happening is that whenever a new stack is "Activated", focus is being given to the contents of the CTabItem. This makes sense for mouse and programmatic activation of a stack, however if the activation comes from the keyboard, this behavior does not feel intuitive. We need to make keyboard traversal through perspectives follow the expected path. I have attached an SWT snippet that mocks up a simple perspective using e4 CTabFolders. The "force focus into contents on activation" behavior is not enabled at all in this snippet, so that we can see what the "natural" tab order is. I am not quite sure at this point what the best way to implement the desired behavior is. It may have to be a combined effort between Platform UI and SWT. CCing Eric and Paul for the Platform UI take on things, and SSQ and Bog for SWT policy and e4 CTabFolder opinions. I think the easiest would be if SWT could guarantee a keyCode in the SWT.Activate Event object whenever Activate comes from the keyboard. Alas, that is not the current behavior of Activate, and I do not know if it is possible to guarantee this on all platforms. If it is, then Platform UI can use the SWT.Activate event.keyCode on CTabFolders as a flag to NOT force focus to the contents, so that keyboard users can follow a natural tab order.
This must be fixed in some satisfactory way by the time 4.2 ships in order to pass the accessibility checklist. CCing McQ because we discussed this issue on the whiteboard last week, and his suggestion was to go with the natural platform behavior, which is what we see when running the attached snippet.
Carolyn, we are currently responding to the SWT.Activate event, is there any way to tell whether this is coming from the KB or not ?
We'll take a look at this in RC1...
Why would we fail accessibility because of this ? Ctrl-3 can get you to any view faster than tabbing...(just askin'...;-).
(In reply to comment #4) > Why would we fail accessibility because of this ? Because it's unpredictable: > Reverse traversal usually follows a different path than forward traversal.
why is there a focus event on CTabFolder traversal? Consider this example. Let's say we are in the editor stack with several open editors. - press Ctrl+Shift+Tab -> focus is on the stack's "minimize" button. Weird, but OK. - press Shift+Tab till we get to an editor tab. Note that we do not fall into the editor on the first tab - press Shift+Tab again to switch to a different editor tab. This time focus shifts to the editor. The focus events is generated in the following call stack (breakpoint on PartServiceImpl line with "invoke(object, Focus.class,"): Shell.setActiveControl(Control) line: 1447 =>(2) Tree(Control).sendFocusEvent(int) line: 2836 Tree(Widget).wmSetFocus(long, long, long) line: 2417 Tree(Control).WM_SETFOCUS(long, long) line: 5152 Tree.WM_SETFOCUS(long, long) line: 7064 Tree(Control).windowProc(long, int, long, long) line: 4598 Tree.windowProc(long, int, long, long) line: 5958 Display.windowProc(long, long, long, long) line: 4976 OS.SetFocus(long) line: not available [native method] Tree(Control).forceFocus() line: 1098 Tree(Control).setTabItemFocus() line: 3650 Tree(Composite).setTabGroupFocus() line: 1145 CTabFolder(Control).traverseGroup(boolean) line: 4293 => (1) CTabFolder(Control).traverse(Event) line: 4058 CTabFolder(Control).translateTraversal(MSG) line: 4032 CTabFolder(Composite).translateTraversal(MSG) line: 1206 Display.translateTraversal(MSG, Control) line: 4794 To my eyes the call stack looks rather strange. (1): CTabFolder(Control).traverseGroup(boolean) line: 4293 At this line code gets a list of 100+ widgets of all different types and calls #setTabGroupFocus() on each. The widget that gets us is the Tree from one of the navigators (Package Explorer most likley). (2): Shell.setActiveControl(Control) line: 1447 At this line Shell gets that navigator tree set as an active control. That triggers listeners that eventually cause a focus event on the part. Note that we are navigating editor stack here which does not have any trees in it.
(In reply to comment 6): > - press Shift+Tab again to switch to a different editor tab. I assume you mean "press left or right arrow to switch to a different editor tab", because Shift+Tab traverses to the next "tab traversal group" (which would likely be the part stack containing the Package Explorer in this case). Arrows traverse to the next "tab traversal item", so you need to type arrow to get to a different editor tab. > This time focus shifts to the editor. I guess that Eclipse UI must force focus to the CTabItem's control (the editor) when a CTabItem is 'selected'? (as well as when it is 'activated'). Correct? I modified the snippet to (sort of) emulate the Eclipse UI behavior. There are 2 booleans at the top of the snippet. If they are both false, then you get regular platform traversal behavior. If they are both true, then you get Eclipse-ish behavior. However, in Eclipse, it is possible to type arrow keys too fast and get non-deterministic behavior (focus shifts to whichever editor you manage to arrow to). With the snippet, I am unable to type fast enough to create a problem. Is it possible that Eclipse is using a timer to asynchronously switch the focus? > To my eyes the call stack looks rather strange. I think (?) that maybe the call stack you are looking at is the traversal over to the Package Explorer Tree after pressing Shift+Tab from one of the editor CTabItems? In which case, you would expect focus to go to the Tree next? Just to double-check, Eclipse UI is definitely switching the focus inside an asyncExec - correct? (I tried switching focus without asynching in my snippet, and I did get some unpredictable behavior).
Created attachment 216308 [details] Modified snippet to emulate Eclipse UI behavior If the non-deterministic behavior can be removed for 4.2.1, then I think it might be possible to explain that forward traversal is different from reverse traversal. We need to get together before 4.2.1 and determine what the behavior *should* be.
Note to self: Make sure that whatever story we end up with also works with minimized stacks. At present while we can Ctrl-Tab to the ToolBar representing the stack and arrow around in it, hitting 'Enter' does *not* open/activate the view associated with the tool item...
Created attachment 217291 [details] Updated patch that has better handling for arrows within a folder This is only a slight change to the original. What it does is inhibit the focus on both selection and activation if the tab change was the result of an arrow traversal. We need to ensure that this approach will work on all platforms (or determine one that does...;-).
commit 7e4f7fe862a8927af779392e2478906c30695916 (in pwebster/start_421) This implements the traversal handling we want for accessibility... Carolyn, thanks a heap for providing the SWT snippet, you can pass the bug back to me now if you want...;-).
All yours man - thanks for giving this so much attention - it's appreciated! Please make sure it goes into both 4.2.1 and 4.3. As soon as you have a build, we'll double-check that it does what we want on the other platforms. Then we still have to come up with some good doc. Some places to put this doc: - http://help.eclipse.org/juno/index.jsp?topic=/org.eclipse.platform.doc.user/concepts/accessibility/text_editor.htm (same as Help -> Help Contents > Workbench User Guide > Concepts > Accessibility features in Eclipse) (this also has 3 sub-pages... we could add another sub-page, if that's useful) - http://wiki.eclipse.org/Accessibility Does UI have a good place to put this information? (or maybe add a link from a UI page to one of the above places)?
I just went through the various scenarios for this on Paul's Linux box and everything appears to be working as expected. Still need to check on the Mac..
Tried 0920-1300 on Mac. There are a number of issues: - apparently we cannot set focus programmatically to trees (probably a different bug) - tab traversal through toolbars "stalls" on the first inactive item (also a different bug) - we got into a state where the tab had focus and Enter did not move focus into the view (this problem even happened on Windows - not sure how to replicate it)
I ran the SWT snippet from comment 10 on Mac, and sure enough, whenever there's a tree in the view, the view does not take focus during keyboard navigation. I can also get the focus "stuck" somewhere in a toolbar simply by navigating with shift+tab through the toolbar and then, when nothing seems to have focus, type arrow keys. Both of these are SWT bugs. SSQ, does either of these sound familiar?
> SSQ, does either of these sound familiar? I thought we fixed the focus getting stuck problem in bug 375619. Apparently there is still a problem in there somewhere. To replicate, run the snippet in comment 10, use the mouse to put focus on "method1()" in the "Package Explorer", and type shift+tab 7 times. (notice that there are 2 invisible items at the front of each toolbar - this is also a problem). Now type tab twice. Keyboard focus is now lost forever and you need to use the mouse to get it back.
Found, fixed, and backported the traversal problem in toolbar - it was a 64-bit problem, described in bug 390713.
Found and fixed the problem in Tree (was also a problem in Table). This is not a problem in 4.2.2 or 3.8.2 because it was recently introduced. See bug 390734 for details.
So, the SWT bugs have been cleared up. Now, we wait for a build and we try it again in Eclipse on Mac. We also need to really hammer on it in Windows and GTK. We should finish the doc, too (see comment 12).
Defered to 4.3
I made the change at http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=67a779fd208e9ff629d53a58fa78e8378a0a6cd9 Carolyn, does this look good? PW
Perfect - thanks, Paul! This change, plus the fixes in the 2 dependent bugs (bug 379263 and bug 384162), go together to make a solution that I am very happy with. Traversal with the tab key in both the forward (tab or ctrl+tab) and reverse (shift+tab or ctrl+shift+tab) direction feels very natural, as well as symmetrical (forward and reverse traverse through the same controls) and comprehensive (the user can traverse to and through every stack). Also, if focus is on a page tab, the user can type Enter to traverse directly to the page tab contents. I have tested this on Windows, Mac, and Linux, with and without a screen reader. Leaving the bug open as a reminder to backport to 4.2.2+.
This can be backported to R4_2_maintenance now, and then marked fixed. The blocking bugs are already backported.
(Note that this does not need to be backported to 3.8.2+... only to 4.2.2+).
This breaks clicking on a view toolbar in 4.x so I'd suggest not backporting this fix at the moment. PW
We need to backport it, so we need to fix clicking on a view toolbar. SSQ, did you say you had an idea for how to fix this?
(In reply to comment #26) > We need to backport it, so we need to fix clicking on a view toolbar. > SSQ, did you say you had an idea for how to fix this? The idea was to put the SWT.Activate listener back only run the code when the SWT.Activate event is coming from a mouse event. This would require us to start setting a detail on the SWT.Activate event. Similar to the SWT.MenuDetect event.
Paul and Eric, if we gave you the ability to know if an Activate came from the keyboard or mouse, would you be able to use that to fix the "activate when clicking on a view toolbar" problem?
OK, you can now tell if an SWT.Activate came from an SWT.MouseDown or not. So you can add that SWT.Activate listener back on to the CTabFolder in StackRenderer.hookControllerLogic() (at approx line 969, after the line for ctf.addCTabFolder2Listener(closeListener); ) This time, check if (event.detail == SWT.MouseDown) before activating the stack. Here's the 11 lines of code to add : // Detect activation...picks up cases where the user clicks on the // (already active) tab ctf.addListener(SWT.Activate, new org.eclipse.swt.widgets.Listener() { public void handleEvent(org.eclipse.swt.widgets.Event event) { if (event.detail == SWT.MouseDown){ CTabFolder ctf = (CTabFolder) event.widget; MElementContainer<MUIElement> stack = (MElementContainer<MUIElement>) ctf.getData(OWNING_ME); activateStack(stack); } } });
http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=79af43ff4a53deab4d0568cea065d311993fac32 This is the StackRenderer part of the fix; SWT is adding code to set the 'detail' field of the event to SWT.MouseDown if the activate was because of a mouse event. This will help Car test the result...
*** Bug 403313 has been marked as a duplicate of this bug. ***
Car, note that this defect is marked as '4.2.2+', meaning that it should be backported into 4.2.2. This means that the SWT fix should also be backported so we'll have to coordinate on when we're going to do this...
Here are the SWT changes to fix the problem in comment 25: Windows master: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=868d20d9606c2e8b0b0b779262a70660ff624466 Windows 4.2 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R4_2_maintenance&id=9a0fd6cabc745a95bd4e129cc1b90caaddedf1b0 Windows 3.8 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R3_8_maintenance&id=74d79d70614141977807e29ed52aaecd7a8c3b36 GTK master: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=883033cc7b617766f9502918d65429670572d928 GTK 4.2 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R4_2_maintenance&id=877dbc6402621ed2fd491ed9056cb21b970ee531 GTK 3.8 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R3_8_maintenance&id=d5ac37988f79814cb50c9f22a1ee5d45430db7da Cocoa master: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=975e98f6ef680ed917c7d22fde80e918d5bef60e Cocoa 4.2 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R4_2_maintenance&id=c20b83f88cbfa8baa26d9704455894819c831a44 Cocoa 3.8 maintenance: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R3_8_maintenance&id=08e8e52ee65cee8c1ded669c5632318fd37dd8e5
Eric, you can backport to 4.2 now. (You do not need to backport to 3.8 ... I only did because we keep our streams consistent).
Backported as http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=R4_2_maintenance&id=e3b9df3c2008866dd859691e3c887637aa638e41 PW