Summary: | no keyboard shortcuts for switching between pages of MultiPageEditorPart | ||
---|---|---|---|
Product: | [Eclipse Project] Platform | Reporter: | Kit Lo <kitlo> |
Component: | SWT | Assignee: | Steve Northover <steve_northover> |
Status: | CLOSED FIXED | QA Contact: | |
Severity: | normal | ||
Priority: | P1 | CC: | dbennett, for.work.things, Kevin_Haaland, n.a.edgar |
Version: | 2.0 | Keywords: | accessibility |
Target Milestone: | 2.0.2 | ||
Hardware: | PC | ||
OS: | Windows 2000 | ||
Whiteboard: |
Description
Kit Lo
2002-07-29 11:52:33 EDT
Ctrl+Page Up and Ctrl+Page Down should switch between pages in a CTabFolder, which is used by MultiPageEditorPart. If the focus widget is a StyledText, however, it processes the keypress before the CTabFolder. An alternative is to use the tab key (or ctrl+tab) to give focus to the folder tab, then use the arrow keys to switch. Moving to SWT to comment on StyledText / CTabFolder interaction. Ctrl+Page Up and Ctrl+Page Down used to work, but stopped working around F2. Please verify. The suggested alternative works. However, after using the right arrow key to switch to the second page in the multi-page editor, I have to use Ctrl+Tab to tab through all the toolbar icons and perspective icons before the focus goes back to the folder tab. So, I need to press about another 10 keystrokes before I can switch to the third page. Try going the other way: Ctrl+Shift+Tab. Ctrl+Shift+Tab works better. Thanks. But I still prefer Ctrl+Page Up and Ctrl+Page Down. We have to find out why it stopped working. Should we leave this bug report open to address the "Ctrl+Page Up and Ctrl+Page Down stopped working" problem? Or, should we just document to use the Ctrl+Shift+Tab way to switch between pages of multi-page editor? Yes, SWT will investigate why Ctrl+Page Up and Ctrl+Page Down stopped working. I have verified that this is a problem in SWT in the following code: public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); shell.setLayout (new FillLayout ()); CTabFolder tabFolder = new CTabFolder (shell, SWT.BORDER); for (int i=0; i<6; i++) { CTabItem item = new CTabItem (tabFolder, SWT.NULL); item.setText ("TabItem " + i); StyledText text = new StyledText (tabFolder, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); item.setControl (text); } shell.open (); tabFolder.getChildren () [0].setFocus (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } Fixed > 20020731 Will the fix be available in Eclipse V2.0.1? So far, this PR is not on the list for 2.0.1. Nick, can you indicate in this PR that you want this fix for R2.0.1? was this ever added to v2.0.1? doing a quick scan of bugs fixed for v2.0.1 it does not look like it was. This was not added to 2.0.1 and unfortunately, I can't remember off hand what the fix was. Kevin, do you want to reopen this PR for 2.0.2? Yes. Minimum requirement is the widget has to be keyboard accessible. The particular key sequence is not as important. If Ctrl-Shift-Tab works then all that is left on this defect for 2.0.2 is to confirm that there isn't a lurking regression that will affect other scenarios. Reopening to be patched to 2.0.2 These I believe are the required changes: Control on Windows: boolean translateTraversal (MSG msg) { int key = msg.wParam; if (key == OS.VK_MENU) { Shell shell = getShell (); int hwndShell = shell.handle; OS.SendMessage (hwndShell, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0); return false; } int hwnd = msg.hwnd; int detail = SWT.TRAVERSE_NONE; boolean doit = true, all = false; boolean lastVirtual = false; int lastKey = key, lastAscii = 0; switch (key) { case OS.VK_ESCAPE: { all = true; lastAscii = 27; int code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0); if ((code & OS.DLGC_WANTALLKEYS) != 0) doit = false; detail = SWT.TRAVERSE_ESCAPE; break; } case OS.VK_RETURN: { all = true; lastAscii = '\r'; int code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0); if ((code & OS.DLGC_WANTALLKEYS) != 0) doit = false; detail = SWT.TRAVERSE_RETURN; break; } case OS.VK_TAB: { /* * NOTE: This code causes Shift+Tab and Ctrl+Tab to * always attempt traversal which is not correct. * The default should be the same as a plain Tab key. * This behavior is currently relied on by StyledText. * * The correct behavior is to give every key to a * control that answers DLGC_WANTALLKEYS. */ lastAscii = '\t'; boolean next = OS.GetKeyState (OS.VK_SHIFT) >= 0; int code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0); if ((code & (OS.DLGC_WANTTAB | OS.DLGC_WANTALLKEYS)) != 0) { if (next && OS.GetKeyState (OS.VK_CONTROL) >= 0) doit = false; } detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS; break; } case OS.VK_UP: case OS.VK_LEFT: case OS.VK_DOWN: case OS.VK_RIGHT: { lastVirtual = true; int code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0); if ((code & (OS.DLGC_WANTARROWS /*| OS.DLGC_WANTALLKEYS*/)) != 0) doit = false; boolean next = key == OS.VK_DOWN || key == OS.VK_RIGHT; detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS; break; } case OS.VK_PRIOR: case OS.VK_NEXT: { all = true; lastVirtual = true; if (OS.GetKeyState (OS.VK_CONTROL) >= 0) return false; /* * The fact that this code is commented causes Ctrl+PgUp * and Ctrl+PgDn to always attempt traversal which is not * correct. This behavior is relied on by StyledText. * * The correct behavior is to give every key to a control * that answers DLGC_WANTALLKEYS. */ // int code = OS.SendMessage (hwnd, OS., 0, 0); // if ((code & OS.DLGC_WANTALLKEYS) != 0) doit = false; detail = key == OS.VK_PRIOR ? SWT.TRAVERSE_PAGE_PREVIOUS : SWT.TRAVERSE_PAGE_NEXT; break; } default: return false; } Event event = new Event (); event.doit = doit; event.detail = detail; Display display = getDisplay (); display.lastKey = lastKey; display.lastAscii = lastAscii; display.lastVirtual = lastVirtual; display.lastNull = false; if (!setKeyState (event, SWT.Traverse)) { return false; } Shell shell = getShell (); Control control = this; do { if (control.traverse (event)) return true; if (!event.doit && control.hooks (SWT.Traverse)) { return false; } if (control == shell) return false; control = control.parent; } while (all && control != null); return false; } Control on GTK: boolean translateTraversal (int gdkEvent) { int detail = SWT.TRAVERSE_NONE; GdkEventKey keyEvent = new GdkEventKey (); OS.memmove (keyEvent, gdkEvent, GdkEventKey.sizeof); int key = keyEvent.keyval; int code = traversalCode (key, gdkEvent); int [] state = new int [1]; OS.gdk_event_get_state (gdkEvent, state); boolean all = false; switch (key) { case OS.GDK_Escape: case OS.GDK_Cancel: { all = true; detail = SWT.TRAVERSE_ESCAPE; break; } case OS.GDK_Return: { all = true; detail = SWT.TRAVERSE_RETURN; break; } case OS.GDK_ISO_Left_Tab: case OS.GDK_Tab: { boolean next = (state [0] & OS.GDK_SHIFT_MASK) == 0; /* * NOTE: This code causes Shift+Tab and Ctrl+Tab to * always attempt traversal which is not correct. * The default should be the same as a plain Tab key. * This behavior is currently relied on by StyledText. * * The correct behavior is to give every key to any * control that wants to see every key. The default * behavior for a Canvas should be to see every key. */ switch (state [0]) { case OS.GDK_SHIFT_MASK: case OS.GDK_CONTROL_MASK: code |= SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_TAB_NEXT; } detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS; break; } case OS.GDK_Up: case OS.GDK_Left: case OS.GDK_Down: case OS.GDK_Right: { boolean next = key == OS.GDK_Down || key == OS.GDK_Right; detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS; break; } case OS.GDK_Page_Up: case OS.GDK_Page_Down: { all = true; if ((state [0] & OS.GDK_CONTROL_MASK) == 0) return false; /* * NOTE: This code causes Ctrl+PgUp and Ctrl+PgDn to always * attempt traversal which is not correct. This behavior is * currently relied on by StyledText. * * The correct behavior is to give every key to any * control that wants to see every key. The default * behavior for a Canvas should be to see every key. */ code |= SWT.TRAVERSE_PAGE_NEXT | SWT.TRAVERSE_PAGE_PREVIOUS; detail = key == OS.GDK_Page_Down ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS; break; } default: return false; } Event event = new Event (); event.doit = (code & detail) != 0; event.detail = detail; event.time = keyEvent.time; setInputState (event, gdkEvent); Shell shell = getShell (); Control control = this; do { if (control.traverse (event)) return true; if (!event.doit && control.hooks (SWT.Traverse)) { return false; } if (control == shell) return false; control = control.parent; } while (all && control != null); return false; } Control on motif: boolean translateTraversal (int key, XKeyEvent xEvent) { int detail = SWT.TRAVERSE_NONE; int code = traversalCode (key, xEvent); boolean all = false; switch (key) { case OS.XK_Escape: case OS.XK_Cancel: { all = true; detail = SWT.TRAVERSE_ESCAPE; break; } case OS.XK_Return: { all = true; detail = SWT.TRAVERSE_RETURN; break; } case OS.XK_Tab: { boolean next = (xEvent.state & OS.ShiftMask) == 0; /* * NOTE: This code causes Shift+Tab and Ctrl+Tab to * always attempt traversal which is not correct. * The default should be the same as a plain Tab key. * This behavior is currently relied on by StyledText. * * The correct behavior is to give every key to any * control that wants to see every key. The default * behavior for a Canvas should be to see every key. */ switch (xEvent.state) { case OS.ControlMask: case OS.ShiftMask: code |= SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_TAB_NEXT; } detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS; break; } case OS.XK_Up: case OS.XK_Left: case OS.XK_Down: case OS.XK_Right: { boolean next = key == OS.XK_Down || key == OS.XK_Right; detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS; break; } case OS.XK_Page_Up: case OS.XK_Page_Down: { all = true; if ((xEvent.state & OS.ControlMask) == 0) return false; /* * NOTE: This code causes Ctrl+PgUp and Ctrl+PgDn to always * attempt traversal which is not correct. This behavior is * currently relied on by StyledText. * * The correct behavior is to give every key to any * control that wants to see every key. The default * behavior for a Canvas should be to see every key. */ code |= SWT.TRAVERSE_PAGE_NEXT | SWT.TRAVERSE_PAGE_PREVIOUS; detail = key == OS.XK_Page_Down ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS; break; } default: return false; } Event event = new Event (); event.doit = (code & detail) != 0; event.detail = detail; event.time = xEvent.time; setKeyState (event, xEvent); Shell shell = getShell (); Control control = this; do { if (control.traverse (event)) return true; if (!event.doit && control.hooks (SWT.Traverse)) { return false; } if (control == shell) return false; control = control.parent; } while (all && control != null); return false; } Thanks. The code looks like it contains other changes that we don't want in 2.0.2. Fixed in 2.0.2. closing old bug |