| Summary: | JAWS reads the parent window for dialog shells | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Tod Creasey <Tod_Creasey> |
| Component: | SWT | Assignee: | Veronika Irvine <veronika_irvine> |
| Status: | RESOLVED FIXED | QA Contact: | |
| Severity: | major | ||
| Priority: | P3 | Keywords: | accessibility, helpwanted |
| Version: | 2.0 | ||
| Target Milestone: | 2.0.1 | ||
| Hardware: | PC | ||
| OS: | Windows 2000 | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 15320, 15576, 20563 | ||
|
Description
Tod Creasey
This is important for M6. Isn't this the same as 15320? Deferred to fix pass 1 Using JAWS it is possible to read the dialog using the JAWS cursor (-) so it is not unreadable. The Ins+B functionality is an extra feature that we do not currently support that we should consider for later releases. It would likely require some sort of discussion with Freedom Scientific (the makers of JAWS). What it is currently reading is the parent shell (the window) of the dialog - special support is required to read a dialog that is not a Windows system dialog. If this change is to wide reaching and not a general solution this should be considered for a later release when we can get support specifically from Freedom Scientific for this function. Pasting the SWT code hacks into here so they are not lost.
Hacks are:
1) in Display
- add field TCHAR windowClass2
- in the init() method, after registering the "SWT_Window" windowClass, do this:
// ===== TEMPORARY CODE - register a different window class for dialogs
windowClass2 = new TCHAR (0, "SWT_Dialog", true);
lpWndClass = new WNDCLASS ();
// make sure we haven't already registered windowClass2
if (OS.GetClassInfo (hInstance, windowClass2, lpWndClass)) {
OS.UnregisterClass (windowClass2, hInstance);
}
// get class info from 32770 and use that to create the new class
TCHAR WC_DIALOGCONTROL = new TCHAR (0, "#32770", true);
lpWndClass = new WNDCLASS ();
OS.GetClassInfo (0, WC_DIALOGCONTROL, lpWndClass);
lpWndClass.hInstance = hInstance;
// System.out.println("32770 style bits=" + Integer.toHexString
(lpWndClass.style));
// FYI, the 32770 style bits were: 0x808 = CS_DBLCLKS | CS_SAVEBITS
//lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW);
//lpWndClass.style |= OS.CS_BYTEALIGNWINDOW | OS.CS_DBLCLKS;
//lpWndClass.lpfnWndProc = windowProc;
//lpWndClass.hCursor = OS.LoadCursor (0, OS.IDC_ARROW);
byteCount = windowClass2.length () * TCHAR.sizeof;
lpszClassName = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
OS.MoveMemory (lpszClassName, windowClass2, byteCount);
lpWndClass.lpszClassName = lpszClassName;
OS.RegisterClass (lpWndClass);
// ===== END TEMP
1) in Shell
- add the following static initializer and methods:
// TEMPORARY CODE
static int DialogProc;
static TCHAR DialogClass;
static {
DialogClass = new TCHAR (0, "#32770", true);
WNDCLASS lpWndClass = new WNDCLASS ();
OS.GetClassInfo (0, DialogClass, lpWndClass);
DialogProc = lpWndClass.lpfnWndProc;
}
int callWindowProc (int msg, int wParam, int lParam) {
if (handle == 0) return 0;
if (true || parent == null) return OS.DefWindowProc (handle, msg,
wParam, lParam);
return OS.CallWindowProc (DialogProc, handle, msg, wParam, lParam);
}
TCHAR windowClass () {
// if (parent != null) return DialogClass;
if (parent != null) return getDisplay ().windowClass2;
return getDisplay ().windowClass;
}
// END TEMP
Note that all of this is hacked code, and we were in the process of commenting
out various bits of it and adding new bits to get everything to work. (i.e.
tried using "#32770" for our dialogs (with/without registering), tried calling
the DialogProc/WindowProc, etc.) The proper code should probably do the right
thing with the dialog proc. The code that worked best for JAWS was to actually
register a window class for our app with the name "#32770", but since we
unregistered the system dialog class in the process, that is what broke the
system dialogs.
Deferring this fix until 3.0 because it is too complex and scary to go in at
this late time. When it goes in, test the following:
- do our custom dialogs look ok?
- does JAWS read the dialog's message label correctly?
- does JAWS INS+B read only the dialog, and not the background window?
- do system dialogs still work?
- does the fix work on Win2K, 98, NT, Me, XP, and CE?
The UI code hacks for org.eclipse.jface.dialogs.MessageDialog were to remove
one layer of composite/layout from the dialogArea (i.e. the area containing the
icon and message label). Reduction of layers in other dialog types should be
considered on a case-by-case basis, seeing whether JAWS can read as much as
possible. (JAWS has trouble reading past too many parent layers, so once the
SWT fixes were in, the recommendation was to flatten the dialogs as much as
possible).
Here is a little test case that helps with the initial testing, although
Eclipse-in-Eclipse should be used for final testing.
import org.eclipse.swt.*;
import org.eclipse.swt.accessibility.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
public class ShellOverrideTest {
static Display display;
static Shell shell;
static Button flat, hallOfMirrors, partialHallOfMirrors, realDialog;
static Shell dialog;
static Label icon, message;
static Button yes, no, cancel;
static Accessible dialogAccessible;
public static void main(String[] args) {
display = new Display();
shell = new Shell(display);
shell.setText("This is the Shell");
shell.setLayout(new GridLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Dialog");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (realDialog.getSelection()) {
MessageBox box = new MessageBox (shell);
box.setText("RealDialog");
box.setMessage("This is the message");
box.open ();
}
else openDialog();
}
});
flat = new Button(shell, SWT.RADIO);
flat.setText("Flat");
flat.setSelection(true);
hallOfMirrors = new Button(shell, SWT.RADIO);
hallOfMirrors.setText("Hall of Mirrors");
partialHallOfMirrors = new Button(shell, SWT.RADIO);
partialHallOfMirrors.setText("Partial Hall of Mirrors");
realDialog = new Button(shell, SWT.RADIO);
realDialog.setText("Real Dialog");
shell.setSize(400, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
static void openDialog() {
dialog = new Shell(shell, SWT.DIALOG_TRIM);
int columns = partialHallOfMirrors.getSelection() ? 2 : 3;
dialog.setLayout(new GridLayout(columns, false));
dialog.setText("FakeDialog");
Composite theParent = dialog;
if (hallOfMirrors.getSelection()) {
Composite composite = new Composite(dialog, SWT.BORDER);
composite.setLayout(new FillLayout());
Composite composite2 = new Composite(composite,
SWT.BORDER);
composite2.setLayout(new GridLayout(3, true));
theParent = composite2;
}
if (partialHallOfMirrors.getSelection()) {
Composite composite = new Composite(dialog, SWT.BORDER);
composite.setLayout(new FillLayout());
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
composite.setLayoutData(data);
composite.setLayout(new GridLayout(3, true));
theParent = composite;
}
Image image = new Image(display,
ShellOverrideTest.class.getResourceAsStream("warning.gif"));
icon = new Label(theParent, SWT.NONE);
icon.setImage(image);
message = new Label(theParent, SWT.WRAP);
message.setText("This is the really really really long very
long message Label.");
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
if (hallOfMirrors.getSelection()) data.horizontalSpan = 2;
data.widthHint = 50;
message.setLayoutData(data);
yes = new Button(theParent, SWT.PUSH);
yes.setText("&Yes");
dialog.setDefaultButton(yes);
yes.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
no = new Button(theParent, SWT.PUSH);
no.setText("&No");
no.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
cancel = new Button(theParent, SWT.PUSH);
cancel.setText("&Cancel");
cancel.setLayoutData(new GridData
(GridData.HORIZONTAL_ALIGN_FILL));
cancel.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
dialog.close();
}
});
dialog.pack();
dialog.open();
}
}
*** Bug 15378 has been marked as a duplicate of this bug. *** Using JAWS cursor is not an adequate solution for this problem. Can OTI provide a JAWS script fix for this problem? No further work will be done on this until post R2.0. If you have a script to contribute we could consider including it. The "32770 Windows work" that CAR describes has been done. I'm sorry but Eclipse will need to change the structure of it's dialogs so that JAWS will read them properly. Tod understands what needs to be done and even had a pre- 2.0 hack that showed this kind of working. Changing to UI. Bug 15320 and bug 15576 cover the UI issues with it not reading indirect children of the shell. Closing this one and moving back to SWT since the problem with reading the parent window has been fixed in SWT. Closing. Fixed in 2.0.1. |